【C#】Socket实现一个即时通讯工具

发布于 2022-10-15  428 次阅读


使用的软件:

  • Visual Studio

使用的编程语言:

  • C#

Github:https://github.com/Mangofang/Messaging


示意图


1.服务端

首先初始化一个Socket对象,用来监听与建立TCP连接。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //SocketType使用Stream类型,ProtocolType使用Tcp协议
socket.Bind(new IPEndPoint(IPAddress.Parse("127.0.0.1"),int.Parse("25565")));
socket.Listen(10);//最大连接数量

通过线程池异步循环建立连接

public List ClientProxSocketList = new List(); //初始化一个List数组用来存储连接的Socket对象
ThreadPool.QueueUserWorkItem(ClientConnect => 
{
    while(true)
    {
        Socket proxSocket = socket.Accept(); //等待客户端连接会阻塞线程 故使用异步
        ClientProxSocketList.Add(proxSocket); //存入数组
    }
});

再建立一个线程池用于接收客户端的消息

ThreadPool.QueueUserWorkItem(ReceiveData => 
{
    byte[] data = new byte[1024 * 1024];//创建缓冲区
    while(true)
    {
        int len = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
        if(len == 0) break;
        str = Encoding.Default.GetString(data, 0, len);//str即为客户端消息
    }
});

发送客户端消息

ThreadPool.QueueUserWorkItem(SendMsg=> 
{
    try
    {
        foreach(Socket proxSocket_ in ClientProxSocketList)//循环遍历ClientProxSocketList给多个不同客户端发送消息
        {
            if (proxSocket_.Connected)
            {
                byte[] data_ = Encoding.Default.GetBytes(str + "\n");
                proxSocket_.Send(data_, 0, data_.Length, SocketFlags.None);
            }
        }
    }
    catch { }
});

2.客户端

与服务器建立连接

private void Form1_Load(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem(ServerConnect =>; 
    {
        Clientsocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        richTextBox1.Text = "正在连接服务器...";
        try
        {
            Clientsocket.Connect(IPAddress.Parse("127.0.0.1"), int.Parse("25565"));
            richTextBox1.Text += "\n你已连接到服务器\n";
        }
        catch (Exception ex)
        {
            richTextBox1.Text += "\n连接失败,正在重试...";
            Thread.Sleep(5000);
            Form1_Load(this, e);
            return;
        }
    }
});

接收客户端消息

ThreadPool.QueueUserWorkItem(ReceiveData =>
                {
                    byte[] data = new byte[1024 * 1024];
                    while (true)
                    {
                        int len = Clientsocket.Receive(data, 0, data.Length, SocketFlags.None);
                        string str = Encoding.Default.GetString(data,0,len);
                        if (len != 0)
                        {
                            
                            richTextBox1.AppendText(str);
                        }
                    }
                });

发送消息到服务器

if (Clientsocket.Connected)
            {
                string ip = GetIP_();
                string send_msg = ip + ":" + textBox1.Text;
                byte[] data = Encoding.Default.GetBytes(send_msg);
                Clientsocket.Send(data, 0, data.Length, SocketFlags.None);
                textBox1.Text = "";
            }