张德长

导航

C# 多人聊天室(基于TCP协议)

2个客户端和1个服务端

客户端将消息发到服务端,服务端将消息进行群发(消息发送方除外),从而实现了多人聊天

 

客户端

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

namespace Client
{
    public partial class Form1 : Form
    {
        Socket socket = null;
        public Form1()
        {
            InitializeComponent();



            btnConnect.Click += BtnConnect_Click;
            btnSend.Click += BtnSend_Click;
            Task.Run(Receive);
        }
        private void Receive()
        {
            while (true)
            {
                if (socket == null) continue;
                if (!socket.Connected) continue;

                try
                {
                    byte[] buffer = new byte[1024];
                    int len = socket.Receive(buffer);
                    if (len < 1) continue;

                    string msg = Encoding.UTF8.GetString(buffer, 0, len);
                    ShowMessage(msg + "\n");
                }
                catch (Exception ex)
                {
                    ShowMessage(ex.Message + "\n");
                    socket = null;
                }

            }

        }
        private void BtnSend_Click(object sender, EventArgs e)
        {
            if (!socket.Connected)
            {
                ShowMessage($"未连接,无法发送");
                return;
            }
            try
            {
                var buffer = Encoding.UTF8.GetBytes(rtxtSend.Text);
                socket.Send(buffer);
                ShowMessage($"发送到:{socket.RemoteEndPoint},消息:{rtxtSend.Text}");
            }
            catch (Exception ex)
            {

                ShowMessage($"发送失败:{socket.RemoteEndPoint},{ex.Message}");
                socket = null;
            }

        }

        private void BtnConnect_Click(object sender, EventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                ShowMessage($"无需重复连接");
                return;
            }
            try
            {
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                ShowMessage($"LocalEndPoint={socket.LocalEndPoint},RemoteEndPoint={socket.RemoteEndPoint}");
                var ipEndPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
                socket.Connect(ipEndPoint);

                if (socket.Connected)
                {
                    ShowMessage($"成功连接到:{socket.RemoteEndPoint}");
                }
            }
            catch (Exception ex)
            {
                ShowMessage($"连接失败:{ex.Message}");
                socket = null;
            }


        }
        private void ShowMessage(string msg)
        {
            //子线程调用
            if (rtxtLog.InvokeRequired)
            {
                rtxtLog.Invoke(new Action(() => rtxtLog.Text += msg + "\n"));
            }
            //主线程调用
            else
            {
                rtxtLog.Text += msg + "\n";
            }


        }
    }
}

服务端

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace Server
{
    class Program
    {
        static Socket socket = null;
        static void Main(string[] args)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.0.117"), 60000));
            socket.Listen(10);
            Console.WriteLine("已启动侦听");
            Task.Run(Connect);

            Console.ReadLine();

        }
        static List<Socket> socketPool = new List<Socket>();
       static Socket acceptSocket = null;
        static void Connect()
        {
            while (true)
            {
                try
                {
                    acceptSocket = socket.Accept();
                    var receiveSocket = acceptSocket;
                    Console.WriteLine($"已接受连接:{receiveSocket.RemoteEndPoint}");
                    socketPool.Add(receiveSocket);
                    Task.Run(Receive);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"连接失败:{ex.Message}");
                }

            }

        }

        static void Receive()
        {
            var receiveSocket = acceptSocket;
            while (true)
            {
                if (receiveSocket == null) continue;
                if (!receiveSocket.Connected) continue;
                try
                {
                    byte[] buffer = new byte[1024];
                    var len = receiveSocket.Receive(buffer);
                    if (len < 1) continue;
                    var msg = Encoding.UTF8.GetString(buffer, 0, len);
                    Console.WriteLine($"来自 {receiveSocket.RemoteEndPoint} 的消息 {msg}");

                    var responseBuffer = Encoding.UTF8.GetBytes($"来自{receiveSocket.RemoteEndPoint} 的消息:{msg}");
                    // receiveSocket.Send(responseBuffer);
                    //清理失效的连接
                    for (int i = socketPool.Count-1; i >=0 ; i--)
                    {
                        if (socketPool[i] == null || !socketPool[i].Connected)
                        {
                            socketPool.RemoveAt(i);
                        }
                    }
                    //广播消息(除了发送消息方之外的,全部广播)
                    foreach (var s in socketPool)
                    {
                        if (s!= receiveSocket)
                        {
                            s.Send(responseBuffer);
                        }
                    }

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message+"\n");
                }
            

            }

        }

    }
}

 

posted on 2023-05-08 18:07  张德长  阅读(526)  评论(1编辑  收藏  举报