首页 学习日记正文

C#开发简单的聊天程序

阿沐 学习日记 2020-06-11 1546 0 C#Socket

C#开发简单的聊天程序

最近在b站看到一个用C#&Socket实现一个简易聊天程序的视频,感觉挺不错的就照着学习了一下,顺便做个笔记。


socket通信原理图:

image.png


服务端(WinForm):

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketServer
{
    public partial class MainForm : Form
    {
        public List<Socket> clientList = new List<Socket>();
        public MainForm()
        {
            InitializeComponent();
        }

        private void startBtn_Click(object sender, EventArgs e)
        {
            //1、创建socket对象
            Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            //2、绑定ip和端口
            socket.Bind(new IPEndPoint(IPAddress.Parse(ipContent.Text),int.Parse(portContent.Text)));
            //3、开启监听
            socket.Listen(10);
            //4、开始接收客户端消息

            ThreadPool.QueueUserWorkItem(new WaitCallback(acceptClient),socket);
            this.AppendTxtToShowLog(string.Format("服务器启动成功!")) ;
        }

        private void acceptClient(object server)
        {
            Socket socket = server as Socket;
            while (true)
            {
                Socket clientSocket=socket.Accept();//接收客户端连接
                clientList.Add(clientSocket);
                this.AppendTxtToShowLog(string.Format("客户端{0}连接成功", clientSocket.RemoteEndPoint.ToString()));
                //不断接收客户端发来的消息
                ThreadPool.QueueUserWorkItem(new WaitCallback(receiveClient),clientSocket);
            }
        }

        private void receiveClient(object client)
        {
            Socket clientSocket = client as Socket;
            byte[] data = new byte[1024 * 1024];
            while (true)
            {
                int len = 0;
                try
                {
                    len = clientSocket.Receive(data, 0, data.Length, SocketFlags.None);//接收字节数组,并获取长度
                }
                catch (Exception)//客户端异常退出
                {

                    try
                    {
                        this.AppendTxtToShowLog(string.Format("客户端{0}异常退出", clientSocket.RemoteEndPoint.ToString()));
                    }
                    catch (Exception)
                    {

                    }
                    clientList.Remove(clientSocket);
                    stopConnect(clientSocket);//关闭连接
                    return;
                }

                if (len <= 0)//客户端正常退出
                {
                    try
                    {
                        this.AppendTxtToShowLog(string.Format("客户端{0}正常退出", clientSocket.RemoteEndPoint.ToString()));
                    }
                    catch (Exception)
                    {

                    }
                    clientList.Remove(clientSocket);
                    stopConnect(clientSocket);//关闭连接
                    return;
                }

                string str=Encoding.Default.GetString(data,0,len);//将字节数组转换成字符串
                this.AppendTxtToShowLog(string.Format("客户端{0}发来信息:{1}",clientSocket.RemoteEndPoint.ToString(),str));

            }
        }

        //关闭连接
        private void stopConnect(Socket clientSocket)
        {
            if (clientSocket.Connected)
            {
                try
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close(100);
                }
                catch (Exception)
                {

                }
            }
        }

        private void AppendTxtToShowLog(string str)//添加日志记录
        {
            if (showLog.InvokeRequired)
            {
                showLog.BeginInvoke(new Action<string>(s =>
                {
                    showLog.Text = string.Format("{0}\r\n{1}", s, this.showLog.Text);
                }), str);
            }
            else
            {
                showLog.Text = string.Format("{0}\r\n{1}", str, this.showLog.Text);
            }
        }

        private void sendBtn_Click(object sender, EventArgs e)
        {
            foreach (var clientSocket in clientList)
            {
                if (clientSocket.Connected)
                {
                    byte[] data = Encoding.Default.GetBytes(this.sendContent.Text);
                    clientSocket.Send(data,0,data.Length,SocketFlags.None);
                }
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            foreach (var clientSocket in clientList)
            {
                if (clientSocket.Connected)
                {
                    try
                    {
                        clientSocket.Shutdown(SocketShutdown.Both);
                        clientSocket.Close();
                    }
                    catch (Exception)
                    {

                    }
                }
            }
        }
    }
}


客户端(WinForm):

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;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SocketClient
{
    public partial class MainForm : Form
    {
        public Socket clientSocket { get; set; }

        public MainForm()
        {
            InitializeComponent();
        }

        private void connectBtn_Click(object sender, EventArgs e)
        {
            //1、创建socket
            Socket socket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            clientSocket = socket;
            //2、连接服务器(ip+port)
            try
            {
                socket.Connect(IPAddress.Parse(ipContent.Text), int.Parse(portContent.Text));
            }
            catch (Exception ex)
            {
                //Thread.Sleep(10);
                //connectBtn_Click(this,e);
                MessageBox.Show("连接失败");
                return;
            }
            //3、开始接收信息
            Thread thread = new Thread(new ParameterizedThreadStart(receiveData));
            thread.IsBackground = true;
            thread.Start(clientSocket);
        }

        private void receiveData(object socket)
        {
            byte[] data = new byte[1024 * 1024];
            while (true)
            {
                int len = 0;
                try
                {
                    len = clientSocket.Receive(data, 0, data.Length - 1, SocketFlags.None);
                }
                catch (Exception)
                {

                    try
                    {
                        this.AppendTxtToShowLog(string.Format("服务端{0}异常退出", clientSocket.RemoteEndPoint.ToString()));
                    }
                    catch (Exception)
                    {

                    }
                    stopConnect();//关闭连接
                    return;
                }

                if (len <= 0)
                {
                    try
                    {
                        this.AppendTxtToShowLog(string.Format("服务端{0}正常退出", clientSocket.RemoteEndPoint.ToString()));
                    }
                    catch (Exception)
                    {

                    }
                    stopConnect();//关闭连接
                    return;
                }

                string str = Encoding.Default.GetString(data,0,len);
                AppendTxtToShowLog(string.Format("服务端发来信息:{0}",str));
            }
        }

        //关闭连接
        private void stopConnect()
        {
            if (clientSocket.Connected)
            {
                try
                {
                    clientSocket.Shutdown(SocketShutdown.Both);
                    clientSocket.Close(100);
                }
                catch (Exception)
                {

                }
            }
        }

        private void AppendTxtToShowLog(string str)//添加日志记录
        {
            if (showLog.InvokeRequired)
            {
                showLog.BeginInvoke(new Action<string>(s =>
                {
                    showLog.Text = string.Format("{0}\r\n{1}", s, this.showLog.Text);
                }), str);
            }
            else
            {
                showLog.Text = string.Format("{0}\r\n{1}", str, this.showLog.Text);
            }
        }

        private void sendBtn_Click(object sender, EventArgs e)
        {

            if (clientSocket.Connected)
            {
                byte[] data = Encoding.Default.GetBytes(sendContent.Text);
                clientSocket.Send(data, 0, data.Length, SocketFlags.None); 
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            //判断是否连接,如果连接则关闭连接
            stopConnect();
        }
    }
}


效果图:

image.png

打赏

评论

Music