asp.net基于C# Socket聊天程序(一个服务端,多个客户端)

作者:袖梨 2022-06-25

部分代码:

命名空间:

 代码如下 复制代码

using System.Net; 
using System.Net.Sockets; 
using System.Threading; 
using System.IO; 

mainform.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace SyncChatServer
{
    public partial class MainForm : Form
    {
        ///


        /// 保存连接的所有用户
        ///

        private List userList = new List();

        ///


        /// 服务器IP地址
        ///
;
        private string ServerIP;

        ///


        /// 监听端口
        ///

        private int port;
        private TcpListener myListener;

        ///


        /// 是否正常退出所有接收线程
        ///

        bool isNormalExit = false;

        public MainForm()
        {
            InitializeComponent();
            lst_State.HorizontalScrollbar = true;
            btn_Stop.Enabled = false;
            SetServerIPAndPort();
        }

        ///


        /// 根据当前程序目录的文本文件‘ServerIPAndPort.txt’内容来设定IP和端口
        /// 格式:127.0.0.1:8885
        ///

        private void SetServerIPAndPort()
        {
            FileStream fs = new FileStream("ServerIPAndPort.txt", FileMode.Open);
            StreamReader sr = new StreamReader(fs);
            string IPAndPort = sr.ReadLine();
            ServerIP = IPAndPort.Split(':')[0]; //设定IP
            port = int.Parse(IPAndPort.Split(':')[1]); //设定端口
            sr.Close();
            fs.Close();
        }


        ///


        /// 开始监听
        ///

        ///
        ///
        private void btn_Start_Click(object sender, EventArgs e)
        {
            myListener = new TcpListener(IPAddress.Parse(ServerIP), port);
            myListener.Start();
            AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接", ServerIP, port));
            //创建一个线程监客户端连接请求
            Thread myThread = new Thread(ListenClientConnect);
            myThread.Start();
            btn_Start.Enabled = false;
            btn_Stop.Enabled = true;
        }

        ///


        /// 接收客户端连接
        ///

        private void ListenClientConnect()
        {
            TcpClient newClient = null;
            while (true)
            {
                try
                {
                    newClient = myListener.AcceptTcpClient();
                }
                catch
                {
                    //当单击‘停止监听’或者退出此窗体时 AcceptTcpClient() 会产生异常
                    //因此可以利用此异常退出循环
                    break;
                }
                //每接收一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息;
                User user = new User(newClient);
                Thread threadReceive = new Thread(ReceiveData);
                threadReceive.Start(user);
                userList.Add(user);
                AddItemToListBox(string.Format("[{0}]进入", newClient.Client.RemoteEndPoint));
                AddItemToListBox(string.Format("当前连接用户数:{0}", userList.Count));
            }

        }

        ///


        /// 处理接收的客户端信息
        ///

        /// 客户端信息
        private void ReceiveData(object userState)
        {
            User user = (User)userState;
            TcpClient client = user.client;
            while (isNormalExit == false)
            {
                string receiveString = null;
                try
                {
                    //从网络流中读出字符串,此方法会自动判断字符串长度前缀
                    receiveString = user.br.ReadString();
                }
                catch (Exception)
                {
                    if (isNormalExit == false)
                    {
                        AddItemToListBox(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint));
                        RemoveUser(user);
                    }
                    break;
                }
                AddItemToListBox(string.Format("来自[{0}]:{1}",user.client.Client.RemoteEndPoint,receiveString));
                string[] splitString = receiveString.Split(',');
                switch(splitString[0])
                {
                    case "Login":
                        user.userName = splitString[1];
                        SendToAllClient(user,receiveString);
                        break;
                    case "Logout":
                        SendToAllClient(user,receiveString);
                        RemoveUser(user);
                        return;
                    case "Talk":
                        string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2);
                        AddItemToListBox(string.Format("{0}对{1}说:{2}",user.userName,splitString[1],talkString));
                        SendToClient(user,"talk," + user.userName + "," + talkString);
                        foreach(User target in userList)
                        {
                            if(target.userName == splitString[1] && user.userName != splitString[1])
                            {
                                SendToClient(target,"talk," + user.userName + "," + talkString);
                                break;
                            }
                        }
                        break;
                    default:
                        AddItemToListBox("什么意思啊:" + receiveString);
                        break;
                }
            }
        }

        ///


        /// 发送消息给所有客户
        ///

        /// 指定发给哪个用户
        /// 信息内容
        private void SendToAllClient(User user, string message)
        {
            string command = message.Split(',')[0].ToLower();
            if (command == "login")
            {
                //获取所有客户端在线信息到当前登录用户
                for (int i = 0; i < userList.Count; i++)
                {
                    SendToClient(user, "login," + userList[i].userName);
                }
                //把自己上线,发送给所有客户端
                for (int i = 0; i < userList.Count; i++)
                {
                    if (user.userName != userList[i].userName)
                    {
                        SendToClient(userList[i], "login," + user.userName);
                    }
                }
            }
            else if(command == "logout")
            {
                for (int i = 0; i < userList.Count; i++)
                {
                    if (userList[i].userName != user.userName)
                    {
                        SendToClient(userList[i], message);
                    }
                }
            }
        }

        ///


        /// 发送 message 给 user
        ///

        /// 指定发给哪个用户
        /// 信息内容
        private void SendToClient(User user, string message)
        {
            try
            {
                //将字符串写入网络流,此方法会自动附加字符串长度前缀
                user.bw.Write(message);
                user.bw.Flush();
                AddItemToListBox(string.Format("向[{0}]发送:{1}", user.userName, message));
            }
            catch
            {
                AddItemToListBox(string.Format("向[{0}]发送信息失败",user.userName));
            }
        }

        ///


        /// 移除用户
        ///

        /// 指定要移除的用户
        private void RemoveUser(User user)
        {
            userList.Remove(user);
            user.Close();
            AddItemToListBox(string.Format("当前连接用户数:{0}",userList.Count));
        }

        private delegate void AddItemToListBoxDelegate(string str);
        ///


        /// 在ListBox中追加状态信息
        ///

        /// 要追加的信息
        private void AddItemToListBox(string str)
        {
            if (lst_State.InvokeRequired)
            {
                AddItemToListBoxDelegate d = AddItemToListBox;
                lst_State.Invoke(d, str);
            }
            else
            {
                lst_State.Items.Add(str);
                lst_State.SelectedIndex = lst_State.Items.Count - 1;
                lst_State.ClearSelected();
            }
        }

        ///


        /// 停止监听
        ///

        ///
        ///
        private void btn_Stop_Click(object sender, EventArgs e)
        {
            AddItemToListBox("开始停止服务,并依次使用户退出!");
            isNormalExit = true;
            for (int i = userList.Count - 1; i >= 0; i--)
            {
                RemoveUser(userList[i]);
            }
            //通过停止监听让 myListener.AcceptTcpClient() 产生异常退出监听线程
            myListener.Stop();
            btn_Start.Enabled = true;
            btn_Stop.Enabled = false;
        }

        ///


        /// 关闭窗口时触发的事件
        ///

        ///
        ///
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (myListener != null)
                btn_Stop.PerformClick();    //引发 btn_Stop 的Click事件
        }
    }
}

 

代码片段:

 代码如下 复制代码
///  
/// 根据当前程序目录的文本文件‘ServerIPAndPort.txt’内容来设定IP和端口 
/// 格式:127.0.0.1:8885 
///

private void SetServerIPAndPort() 

    FileStream fs = new FileStream("ServerIPAndPort.txt", FileMode.Open); 
    StreamReader sr = new StreamReader(fs); 
    string IPAndPort = sr.ReadLine(); 
    ServerIP = IPAndPort.Split(':')[0]; //设定IP 
    port = int.Parse(IPAndPort.Split(':')[1]); //设定端口 
    sr.Close(); 
    fs.Close(); 

 
 
///  
/// 开始监听 
///
 
///  
///
private void btn_Start_Click(object sender, EventArgs e) 

    myListener = new TcpListener(IPAddress.Parse(ServerIP), port); 
    myListener.Start(); 
    AddItemToListBox(string.Format("开始在{0}:{1}监听客户连接", ServerIP, port)); 
    //创建一个线程监客户端连接请求 
    Thread myThread = new Thread(ListenClientConnect); 
    myThread.Start(); 
    btn_Start.Enabled = false; 
    btn_Stop.Enabled = true; 

 
///  
/// 接收客户端连接 
///

private void ListenClientConnect() 

    TcpClient newClient = null; 
    while (true) 
    { 
        try 
        { 
            newClient = myListener.AcceptTcpClient(); 
        } 
        catch 
        { 
            //当单击‘停止监听’或者退出此窗体时 AcceptTcpClient() 会产生异常 
            //因此可以利用此异常退出循环 
            break; 
        } 
        //每接收一个客户端连接,就创建一个对应的线程循环接收该客户端发来的信息; 
        User user = new User(newClient); 
        Thread threadReceive = new Thread(ReceiveData); 
        threadReceive.Start(user); 
        userList.Add(user); 
        AddItemToListBox(string.Format("[{0}]进入", newClient.Client.RemoteEndPoint)); 
        AddItemToListBox(string.Format("当前连接用户数:{0}", userList.Count)); 
    } 
 

 
///  
/// 处理接收的客户端信息 
///
 
/// 客户端信息
private void ReceiveData(object userState) 

    User user = (User)userState; 
    TcpClient client = user.client; 
    while (isNormalExit == false) 
    { 
        string receiveString = null; 
        try 
        { 
            //从网络流中读出字符串,此方法会自动判断字符串长度前缀 
            receiveString = user.br.ReadString(); 
        } 
        catch (Exception) 
        { 
            if (isNormalExit == false) 
            { 
                AddItemToListBox(string.Format("与[{0}]失去联系,已终止接收该用户信息", client.Client.RemoteEndPoint)); 
                RemoveUser(user); 
            } 
            break; 
        } 
        AddItemToListBox(string.Format("来自[{0}]:{1}",user.client.Client.RemoteEndPoint,receiveString)); 
        string[] splitString = receiveString.Split(','); 
        switch(splitString[0]) 
        { 
            case "Login": 
                user.userName = splitString[1]; 
                SendToAllClient(user,receiveString); 
                break; 
            case "Logout": 
                SendToAllClient(user,receiveString); 
                RemoveUser(user); 
                return; 
            case "Talk": 
                string talkString = receiveString.Substring(splitString[0].Length + splitString[1].Length + 2); 
                AddItemToListBox(string.Format("{0}对{1}说:{2}",user.userName,splitString[1],talkString)); 
                SendToClient(user,"talk," + user.userName + "," + talkString); 
                foreach(User target in userList) 
                { 
                    if(target.userName == splitString[1] && user.userName != splitString[1]) 
                    { 
                        SendToClient(target,"talk," + user.userName + "," + talkString); 
                        break; 
                    } 
                } 
                break; 
            default: 
                AddItemToListBox("什么意思啊:" + receiveString); 
                break; 
        } 
    } 

user.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace SyncChatServer
{
    class User
    {
        public TcpClient client { get; private set; }
        public BinaryReader br { get; private set; }
        public BinaryWriter bw { get; private set; }
        public string userName { get; set; }

        public User(TcpClient client)
        {
            this.client = client;
            NetworkStream networkStream = client.GetStream();
            br = new BinaryReader(networkStream);
            bw = new BinaryWriter(networkStream);
        }

        public void Close()
        {
            br.Close();
            bw.Close();
            client.Close();
        }

    }
}

 

program.cs

 代码如下 复制代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace SyncChatServer
{
    static class Program
    {
        ///


        /// 应用程序的主入口点。
        ///

        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new MainForm());
        }
    }
}

 

main.cs

 代码如下 复制代码

namespace SyncChatServer
{
    partial class MainForm
    {
        ///


        /// 必需的设计器变量。
        ///

        private System.ComponentModel.IContainer components = null;

        ///


        /// 清理所有正在使用的资源。
        ///

        /// 如果应释放托管资源,为 true;否则为 false。
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        ///


        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        ///

        private void InitializeComponent()
        {
            this.groupBox1 = new System.Windows.Forms.GroupBox();
            this.lst_State = new System.Windows.Forms.ListBox();
            this.btn_Start = new System.Windows.Forms.Button();
            this.btn_Stop = new System.Windows.Forms.Button();
            this.groupBox1.SuspendLayout();
            this.SuspendLayout();
            //
            // groupBox1
            //
            this.groupBox1.Controls.Add(this.lst_State);
            this.groupBox1.Location = new System.Drawing.Point(12, 12);
            this.groupBox1.Name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(523, 327);
            this.groupBox1.TabIndex = 0;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "状态信息";
            //
            // lst_State
            //
            this.lst_State.Dock = System.Windows.Forms.DockStyle.Fill;
            this.lst_State.FormattingEnabled = true;
            this.lst_State.ItemHeight = 12;
            this.lst_State.Location = new System.Drawing.Point(3, 17);
            this.lst_State.Name = "lst_State";
            this.lst_State.Size = new System.Drawing.Size(517, 304);
            this.lst_State.TabIndex = 0;
            //
            // btn_Start
            //
            this.btn_Start.Location = new System.Drawing.Point(126, 346);
            this.btn_Start.Name = "btn_Start";
            this.btn_Start.Size = new System.Drawing.Size(75, 23);
            this.btn_Start.TabIndex = 1;
            this.btn_Start.Text = "开始监听";
            this.btn_Start.UseVisualStyleBackColor = true;
            this.btn_Start.Click += new System.EventHandler(this.btn_Start_Click);
            //
            // btn_Stop
            //
            this.btn_Stop.Location = new System.Drawing.Point(322, 346);
            this.btn_Stop.Name = "btn_Stop";
            this.btn_Stop.Size = new System.Drawing.Size(75, 23);
            this.btn_Stop.TabIndex = 2;
            this.btn_Stop.Text = "停止监听";
            this.btn_Stop.UseVisualStyleBackColor = true;
            this.btn_Stop.Click += new System.EventHandler(this.btn_Stop_Click);
            //
            // MainForm
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(547, 375);
            this.Controls.Add(this.btn_Stop);
            this.Controls.Add(this.btn_Start);
            this.Controls.Add(this.groupBox1);
            this.Name = "MainForm";
            this.Text = "SyncChatServer";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.MainForm_FormClosing);
            this.groupBox1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.GroupBox groupBox1;
        private System.Windows.Forms.ListBox lst_State;
        private System.Windows.Forms.Button btn_Start;
        private System.Windows.Forms.Button btn_Stop;
    }
}

以上是不完整的代码片段,由于代码太多这里贴出来肯定眼花缭乱的。。

有需要的朋友还是下载源码看把

点击下载源文件

相关文章

精彩推荐