C#语言使用Socket 实现简易聊天室功能,有源码并且可以直接运行

声明:第四部分是讲诉如何直接使用服务端和客户端,如果不想复制,只想查看效果可以执行跳转。
如果你将服务端挂在在自己的电脑上,则朋友在和你同一个WIFI下才能进行聊天。
如果将服务端挂载到服务器上,则可以在不同的地方聊天。(当然客户端的设置的连接服务端的IP要设置为公网IP)

1.Socket服务端代码

1.1 新建一个控制台程序(类似于命令行界面)
1.2 在Nuget中导入Socket
在这里插入图片描述
1.3 新建一个CS文件,复制以下代码。

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

namespace SocketServer
{
    public class SocketService
    {
        private Socket socket = null;
        private string IP = string.Empty;
        private int Port = 0;
        private byte[] buffer = new byte[1024 * 1024 * 2];
        private Dictionary<string, Socket> clientDic = new Dictionary<string, Socket>();
        public List<string> UserList = new List<string>();
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="ip">监听的IP</param>
        /// <param name="port">监听的端口</param>
        public SocketService(string ip, int port)
        {
            this.IP = ip;
            this.Port = port;
        }
        public SocketService(int port)
        {
            this.IP = "0.0.0.0";
            this.Port = port;
        }


        public void SocketListen()
        {
            try
            {
                //1.0 实例化套接字(IP4寻找协议,流式协议,TCP协议)
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //2.0 创建IP对象
                IPAddress address = IPAddress.Parse(IP);
                //3.0 创建网络端口,包括ip和端口
                IPEndPoint endPoint = new IPEndPoint(address, Port);
                //4.0 绑定套接字
                socket.Bind(endPoint);
                //5.0 设置最大连接数
                socket.Listen(int.MaxValue);

                WriteLog.Write("服务器已开启!");
                Console.WriteLine("服务器已开启!");
                //6.0 开始监听
                Thread thread = new Thread(ListenClientConnect);
                thread.Start();
            }
            catch (Exception ex)
            {
                WriteLog.Write(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 监听客户端连接
        /// </summary>
        private void ListenClientConnect()
        {
            try
            {
                while (true)
                {
                    //Socket创建的新连接
                    Socket clientSocket = socket.Accept();
                    //连接成功后会往下走
                    EndPoint clientipe = clientSocket.RemoteEndPoint;
                    //打印日志
                    WriteLog.Write($"接收客户端【{clientipe}】连接...");
                    Console.WriteLine($"接收客户端【{clientipe}】连接...");
                    string IP = clientipe.ToString();
                    //通过IP绑定每个socket
                    clientDic.Add(clientipe.ToString(), clientSocket);

                    WriteLog.Write($"用户【{clientipe}】上线");
                    Console.WriteLine($"用户【{clientipe}】上线");

                    UserList.Add(clientipe.ToString());

                    string Users = string.Empty;
                    foreach (var item in UserList)
                    {
                        Users = item + "," + Users;
                    }
                    foreach (var kvp in clientDic)
                    {
                        kvp.Value.Send(Encoding.UTF8.GetBytes($"{clientipe},进入聊天"));
                        kvp.Value.Send(Encoding.UTF8.GetBytes($"Users,{Users}"));
                    }
                    Thread thread = new Thread(ReceiveMessage);
                    thread.Start(clientSocket);
                }
            }
            catch (Exception ex)
            {
                WriteLog.Write(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }

        /// <summary>
        /// 接收客户端消息
        /// </summary>
        /// <param name="socket">来自客户端的socket</param>
        private void ReceiveMessage(object socket)
        {
            try
            {
                Socket clientSocket = socket as Socket;
                while (true)
                {
                    try
                    {
                        //获取从客户端发来的数据
                        int length = clientSocket.Receive(buffer);
                        string stringFromBytes = Encoding.UTF8.GetString(buffer, 0, length);

                        WriteLog.Write($"接收客户端消息:{stringFromBytes}");
                        Console.WriteLine($"接收客户端消息:{stringFromBytes}");

                        EndPoint clientipe = clientSocket.RemoteEndPoint;

                        foreach (var kvp in clientDic)
                        {
                            kvp.Value.Send(Encoding.UTF8.GetBytes($"{clientipe},{stringFromBytes}"));
                        }
                    }
                    catch (Exception ex)
                    {
                        WriteLog.Write(ex.Message);
                        Console.WriteLine(ex.Message);
                        //一般服务端关闭后会报错所以这里下线后断开Socket并修改该IP状态

                        EndPoint clientipe = clientSocket.RemoteEndPoint;
                        clientDic.Remove(clientipe.ToString());

                        clientSocket.Shutdown(SocketShutdown.Both);
                        clientSocket.Close();

                        WriteLog.Write($"用户【{clientipe}】下线");
                        Console.WriteLine($"用户【{clientipe}】下线");

                        UserList.Remove(clientipe.ToString());
                        string Users = string.Empty;
                        foreach (var item in UserList)
                        {
                            Users = Users + "," + item;
                        }
                        foreach (var kvp in clientDic)
                        {
                            kvp.Value.Send(Encoding.UTF8.GetBytes($"Users,{Users}"));
                            kvp.Value.Send(Encoding.UTF8.GetBytes($"{clientipe},退出聊天"));
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog.Write(ex.Message);
                Console.WriteLine(ex.Message);
            }
        }
    }
}

其中WriteLog.Write()是自定义的日志存储方法,可以不用删掉

2.客户端代码

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Text;
using System.Threading;
using COM;
using SocketServer;
using System.Windows;
using System.Xml.Linq;
using COM.Common;
using SocketClient.Models;
using SocketServer.Common;
using SocketClient.Common;
using SocketClient.Views;
using System.Collections.Generic;
using System.Timers;


namespace SocketClient.ViewModels
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        private System.Timers.Timer timer { get; set; }
        public Socket sockets;
        private byte[] buffer = new byte[1024 * 1024 * 2];

        public string _SendMessage;
        public string SendMessage
        {
            get { return _SendMessage; }
            set { _SendMessage = value; OnPropertyChanged("SendMessage"); }
        }

        public ObservableCollection<ChatHistory> _Result;
        public ObservableCollection<ChatHistory> Result
        {
            get { return _Result; }
            set { _Result = value; OnPropertyChanged("Result"); }
        }
        public ObservableCollection<User> _ListUser = new ObservableCollection<User>();
        public ObservableCollection<User> ListUser
        {
            get { return _ListUser; }
            set { _ListUser = value; OnPropertyChanged("ListUser"); }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }


        public DelegateCommand SendCommand { get; set; }
        public DelegateCommand ShrinkCommand { get; set; }
        public DelegateCommand CloseCommand { get; set; }
        public DelegateCommand MenuCommand { get; set; }
        public DelegateCommand KeyEventCommand { get; set; }
        public MainWindowViewModel()
        {
            SendCommand = new DelegateCommand(SendEven);
            ShrinkCommand = new DelegateCommand(ShrinkEven);
            CloseCommand = new DelegateCommand(CloseEven);
            MenuCommand = new DelegateCommand(MenuEven);
            KeyEventCommand = new DelegateCommand(SendEven);
            Result = new ObservableCollection<ChatHistory>();
            ClientConnect();


        }
        private void MenuEven(object Win)
        {
            //UserWindow win = new UserWindow();
            //win.ShowDialog();

        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void CloseEven(object Win)
        {
            sockets.Shutdown(SocketShutdown.Both);
            sockets.Close();
            Window window = Win as Window;
            window.Close();
            window.WindowState = WindowState.Minimized;


        }

        /// <summary>
        /// 缩小
        /// </summary>
        /// <exception cref="NotImplementedException"></exception>
        private void ShrinkEven(object Win)
        {
            Window window = Win as Window;
            window.WindowState = WindowState.Minimized;
        }


        /// <summary>
        /// 发送消息
        /// </summary>
        private void SendEven()
        {
            try
            {
                string sendMessage = string.Format(SendMessage);
                sockets.Send(Encoding.UTF8.GetBytes(sendMessage));
                SendMessage = string.Empty;
            }
            catch (Exception ex)
            {
                WriteLog.Write(ex.Message);
            }
        }

        /// <summary>
        /// 连接Socket
        /// </summary>
        public void ClientConnect()
        {
            /// <summary>
            /// 开启服务,连接服务端
            /// </summary>
            try
            {
                //1.0 实例化套接字(IP4寻址地址,流式传输,TCP协议)
                sockets = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //2.0 创建IP对象
                IPAddress address = IPAddress.Parse(Publics.ServerIPAddress);
                //3.0 创建网络端口包括ip和端口
                IPEndPoint endPoint = new IPEndPoint(address, 8080);
                //固定端口
                sockets.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), 9999));
                //4.0 建立连接
                sockets.Connect(endPoint);
                Console.WriteLine("连接服务器成功");
                //Publics.ClientName = sockets.LocalEndPoint.ToString();
                //Publics.IP = sockets.LocalEndPoint.ToString();

                //开启线程接收数据
                Thread thread = new Thread(Message);
                thread.Start();
            }
            catch (Exception ex)
            {
                sockets.Shutdown(SocketShutdown.Both);
                sockets.Close();
                Console.WriteLine(ex.Message);
                WriteLog.Write(ex.Message);
            }


        }

        /// <summary>
        /// 接收数据
        /// </summary>
        public void Message()
        {
            try
            {
                //5.0 接收数据
                while (true)
                {
                    int lengths = sockets.Receive(buffer);
                    string stringFromBytes1 = Encoding.UTF8.GetString(buffer, 0, lengths);
                    string[] splitString = stringFromBytes1.Split(',');
                    if (splitString.Length > 0)
                    {
                        if (!string.IsNullOrEmpty(splitString[0]))
                        {
                            if (splitString[0] == "Users")
                            {
                                Application.Current.Dispatcher.Invoke((Action)(() =>
                                {
                                    ListUser = new ObservableCollection<User>();
                                    for (int i = 1; i < splitString.Length; i++)
                                    {
                                        User user = new User()
                                        {
                                            Name = splitString[i],
                                        };
                                        ListUser.Add(user);
                                    }
                                }));
                            }
                            else
                            {
                                Application.Current.Dispatcher.Invoke((Action)(() =>
                                {
                                    Result.Add(new ChatHistory() { UserName = splitString[0], Message = splitString[1] });
                                }));
                            }
                        }
                        else
                        {
                            WriteLog.Write("服务器传入的第一条数据为空");
                        }
                    }
                    else
                    {
                        WriteLog.Write("服务器传入的数据为空");
                    }
                }
            }
            catch (Exception ex)
            {
                WriteLog.Write(ex.Message);
            }
        }


    }


}

客户端代码我只放置了MVVM框架中的ViewModel中的代码,界面代码请看本文最末的Gitee链接
以上就是主要内容,剩余内容自己研究。

3.运行展示

3.1 服务器
在这里插入图片描述

3.2客户端
在这里插入图片描述

4.直接使用

如果想直接使用服务器和客户端,也可以跳过开发过程
服务器启动流程
在这里插入图片描述
客户端启动
需要修改连接服务端的IP地址,使用Win+R打开运行窗口,输入CMD 进入命令行界面。输入ipconfig
在这里插入图片描述
获取到对应的IP

然后进入这个地方,用记事本打开.config文件
在这里插入图片描述
将此地方的IP改为自己放置服务端的IP
在这里插入图片描述

然后打开SocketClient运行程序进入聊天室界面
在这里插入图片描述

源码地址如下:
服务端点击此处
客户端点击此处

  • 8
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现C#简易聊天室,可以使用Socket来进行操作。首先,声明一个套接字(Socket)作为监听套接字,使用AddressFamily.InterNetwork、SocketType.Stream和ProtocolType.Tcp来创建这个套接字。接下来,需要设置服务器的IP地址和端口号。然后,使用Socket的Bind方法将套接字绑定到指定的IP地址和端口上。接着,使用Socket的Listen方法开始监听连接请求。当有客户端连接请求时,可以使用Accept方法接受连接,并创建一个新的套接字来处理该连接。这样就可以与客户端进行通信了。 在聊天室中,可以使用多线程来处理多个客户端的连接。当有新的客户端连接时,创建一个新的线程来处理该连接,这样就可以同时处理多个客户端的消息收发。 在处理客户端消息的过程中,可以使用Socket的Receive和Send方法来接收和发送数据。可以使用StreamReader和StreamWriter类来简化数据的读取和写入操作。 通过这些步骤,就可以实现一个简单的C# Socket聊天室。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [C#基于Socket的简单聊天室实践](https://blog.csdn.net/wyqlxy/article/details/46923611)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值