C#简单的客户端和服务端的功能,简单的聊天室(Winform TCP)

 客户端代码:

界面代码:

namespace ClientWinform
{
    partial class Form1
    {
        /// <summary>
        ///  Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        ///  Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        ///  Required method for Designer support - do not modify
        ///  the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.SendToBtn = new System.Windows.Forms.Button();
            this.IPText = new System.Windows.Forms.TextBox();
            this.PortText = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.SendMsg = new System.Windows.Forms.TextBox();
            this.TextMsg = new System.Windows.Forms.RichTextBox();
            this.ConnectBtn = new System.Windows.Forms.Button();
            this.DisconnectBtn = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // SendToBtn
            // 
            this.SendToBtn.Location = new System.Drawing.Point(713, 415);
            this.SendToBtn.Name = "SendToBtn";
            this.SendToBtn.Size = new System.Drawing.Size(75, 23);
            this.SendToBtn.TabIndex = 0;
            this.SendToBtn.Text = "发送";
            this.SendToBtn.UseVisualStyleBackColor = true;
            this.SendToBtn.Click += new System.EventHandler(this.SendToBtn_Click);
            // 
            // IPText
            // 
            this.IPText.Location = new System.Drawing.Point(35, 6);
            this.IPText.Name = "IPText";
            this.IPText.Size = new System.Drawing.Size(209, 23);
            this.IPText.TabIndex = 0;
            this.IPText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.IPText_OnKeyDown);
            // 
            // PortText
            // 
            this.PortText.Location = new System.Drawing.Point(295, 6);
            this.PortText.Name = "PortText";
            this.PortText.Size = new System.Drawing.Size(124, 23);
            this.PortText.TabIndex = 3;
            this.PortText.KeyDown += new System.Windows.Forms.KeyEventHandler(this.PortText_OnKeyDown);
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(10, 9);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(19, 17);
            this.label1.TabIndex = 0;
            this.label1.Text = "IP";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(257, 10);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(32, 17);
            this.label2.TabIndex = 2;
            this.label2.Text = "端口";
            // 
            // SendMsg
            // 
            this.SendMsg.Location = new System.Drawing.Point(10, 415);
            this.SendMsg.Name = "SendMsg";
            this.SendMsg.Size = new System.Drawing.Size(697, 23);
            this.SendMsg.TabIndex = 4;
            this.SendMsg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.OnKeyDown_MsgSend);
            // 
            // TextMsg
            // 
            this.TextMsg.Location = new System.Drawing.Point(10, 35);
            this.TextMsg.Name = "TextMsg";
            this.TextMsg.Size = new System.Drawing.Size(778, 374);
            this.TextMsg.TabIndex = 5;
            this.TextMsg.Text = "";
            this.TextMsg.TextChanged += new System.EventHandler(this.TextMsg_TextChanged);
            // 
            // ConnectBtn
            // 
            this.ConnectBtn.Location = new System.Drawing.Point(445, 6);
            this.ConnectBtn.Name = "ConnectBtn";
            this.ConnectBtn.Size = new System.Drawing.Size(83, 23);
            this.ConnectBtn.TabIndex = 6;
            this.ConnectBtn.Text = "连接服务器";
            this.ConnectBtn.UseVisualStyleBackColor = true;
            this.ConnectBtn.Click += new System.EventHandler(this.ConnectBtn_Click);
            // 
            // DisconnectBtn
            // 
            this.DisconnectBtn.Location = new System.Drawing.Point(545, 6);
            this.DisconnectBtn.Name = "DisconnectBtn";
            this.DisconnectBtn.Size = new System.Drawing.Size(79, 23);
            this.DisconnectBtn.TabIndex = 7;
            this.DisconnectBtn.Text = "断开服务器";
            this.DisconnectBtn.UseVisualStyleBackColor = true;
            this.DisconnectBtn.Click += new System.EventHandler(this.DisconnectBtn_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.DisconnectBtn);
            this.Controls.Add(this.ConnectBtn);
            this.Controls.Add(this.TextMsg);
            this.Controls.Add(this.SendMsg);
            this.Controls.Add(this.IPText);
            this.Controls.Add(this.PortText);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.SendToBtn);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private Button SendToBtn;
        private TextBox IPText;
        private Label label1;
        private Label label2;
        private TextBox PortText;
        private TextBox SendMsg;
        private RichTextBox TextMsg;
        private Button ConnectBtn;
        private Button DisconnectBtn;
    }
}

客户端执行代码: 

using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ClientWinform
{
    public partial class Form1 : Form
    {

        private IPAddress remoteIPAddress;

        private int remotePort;

        private Socket socket;

        private byte[] dataReceive = new byte[1024];

        private Thread th1;

        public Form1()
        {
            InitializeComponent();
        }

        private void Init()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //定义本地接收数据的端口
            IPEndPoint localHost = new IPEndPoint(IPAddress.Any, 30080);
            socket.Bind(localHost);
        }
        private void OnChangeTextMsg(string msg)
        {
            this.TextMsg.AppendText(msg);
        }
        private void IPText_OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
            {
                if (!IPAddress.TryParse(IPText.Text, out remoteIPAddress))
                {
                    MessageBox.Show("请输入正确的IP地址");
                    IPText.Text = "";
                }
                else
                {
                    TextMsg.AppendText($"IP:{remoteIPAddress}\r\n");
                }
            }
        }

        private void PortText_OnKeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter || e.KeyCode == Keys.Tab)
            {
                if (!int.TryParse(PortText.Text, out remotePort))
                {
                    MessageBox.Show("请输入正确的端口");
                    PortText.Text = "";
                }
                else
                {
                    if (remotePort < 0 || remotePort > 65535)
                    {
                        MessageBox.Show("输入的端口越界,请输入正确的端口");
                        PortText.Text = "";
                    }
                    else
                    {
                        TextMsg.AppendText($"Port:{remotePort}\r\n");
                    }
                }
            }
        }
        /// <summary>
        /// 使消息面板一直显示最新的消息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TextMsg_TextChanged(object sender, EventArgs e)
        {
            this.TextMsg.SelectionStart = this.TextMsg.Text.Length;
            this.TextMsg.SelectionLength = 0;
            this.TextMsg.ScrollToCaret();
        }

        private void SendToBtn_Click(object sender, EventArgs e)
        {
            if (!CheckSocketVaild() | !CheckTCPVaild())
            {
                return;
            }
            string msg = this.SendMsg.Text;
            if (!string.IsNullOrEmpty(msg))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(msg);
                socket.Send(bytes);
            }
            this.SendMsg.Text = "";
            TextMsg.AppendText($"\r\n客户端发送消息:{msg}");
        }

        private void ConnectBtn_Click(object sender, EventArgs e)
        {
            if (!CheckTCPVaild())
            {
                TextMsg.AppendText($"输入的IP[{remoteIPAddress}]或者端口号[{remotePort}]出错\r\n");
                return;
            }
            Init();
            try
            {
                IPEndPoint remoteIPEndPoint = new IPEndPoint(remoteIPAddress, remotePort);
                EndPoint remoteEndPoint = (EndPoint)remoteIPEndPoint;
                socket.ReceiveTimeout = 15 * 1000;
                socket.SendTimeout = 15 * 1000;
                socket.BeginConnect(remoteEndPoint, OnConnect, socket);
            }
            catch
            {
                socket?.Close();
                socket = null;
                TextMsg.AppendText($"连接不上服务器\r\n");
            }
        }
        /// <summary>
        /// 客户端未连接到服务器的时候也会触发回调
        /// </summary>
        /// <param name="ar"></param>
        private void OnConnect(IAsyncResult ar)
        {
            if (ar.AsyncState != null)
            {
                Socket s = (Socket)ar.AsyncState;
                if (s.Connected)
                {
                    s.EndConnect(ar);
                    th1 = new Thread(OnReceive);
                    th1.IsBackground = true;
                    th1.Start(socket);
                }
                else
                {
                    socket?.Close();
                    socket = null;
                    this.Invoke(OnChangeTextMsg, $"连接不上服务器\r\n");
                }
            }
        }

        private void OnReceive(object o)
        {
            try
            {
                //同步
                //while (isReceive)
                //{
                //    socket.Receive(dataReceive);
                //    if (dataReceive.Length > 0)
                //    {
                //        string msg = Encoding.UTF8.GetString(dataReceive);
                //        this.Invoke(OnChangeTextMsg, $"\r\n服务器返回消息:{msg}");
                //    }
                //}
                //异步
                socket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveAsync, socket);
            }
            catch (Exception e)
            {
                this.Invoke(OnChangeTextMsg, $"连接不上服务器,错误原因[{e.Message}],[{e.StackTrace}]\r\n");
                socket?.Close();
            }
        }

        private void OnReceiveAsync(IAsyncResult ar)
        {
            if (ar.AsyncState != null)
            {
                Socket s = (Socket)ar.AsyncState;
                if (s.Connected)
                {
                    s.EndReceive(ar);
                    if (dataReceive.Length > 0)
                    {
                        string msg = Encoding.UTF8.GetString(dataReceive);
                        this.Invoke(OnChangeTextMsg, $"\r\n服务器返回消息:{msg}");
                        dataReceive = new byte[1024];
                        socket.BeginReceive(dataReceive, 0, dataReceive.Length, SocketFlags.None, OnReceiveAsync, socket);
                    }
                }
            }
        }

        private void DisconnectBtn_Click(object sender, EventArgs e)
        {
            if (!CheckSocketVaild() || !CheckTCPVaild())
            {
                return;
            }
            byte[] bytes = Encoding.UTF8.GetBytes("close");
            socket.Send(bytes);
            socket?.Close();

            this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
        }

        /// <summary>
        /// 检查合法性
        /// </summary>
        /// <returns></returns>
        private bool CheckTCPVaild()
        {
            if (remoteIPAddress == null || remotePort <= 0)
            {
                return false;
            }
            return true;
        }

        private bool CheckSocketVaild()
        {
            if (socket == null)
            {
                return false;
            }
            return true;
        }

        private void OnKeyDown_MsgSend(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SendToBtn_Click(sender, e);
            }
        }
    }
}

服务端:

界面代码:

namespace ServerWinform
{
    partial class Form1
    {
        /// <summary>
        ///  Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        ///  Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        ///  Required method for Designer support - do not modify
        ///  the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.TextMsg = new System.Windows.Forms.RichTextBox();
            this.SendMsg = new System.Windows.Forms.TextBox();
            this.SendTo = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // TextMsg
            // 
            this.TextMsg.Location = new System.Drawing.Point(12, 12);
            this.TextMsg.Name = "TextMsg";
            this.TextMsg.Size = new System.Drawing.Size(776, 387);
            this.TextMsg.TabIndex = 0;
            this.TextMsg.Text = "";
            this.TextMsg.TextChanged += new System.EventHandler(this.TextMsg_TextChanged);
            // 
            // SendMsg
            // 
            this.SendMsg.Location = new System.Drawing.Point(12, 415);
            this.SendMsg.Name = "SendMsg";
            this.SendMsg.Size = new System.Drawing.Size(695, 23);
            this.SendMsg.TabIndex = 1;
            this.SendMsg.KeyDown += new System.Windows.Forms.KeyEventHandler(this.SendMsg_KeyDown);
            // 
            // SendTo
            // 
            this.SendTo.Location = new System.Drawing.Point(713, 415);
            this.SendTo.Name = "SendTo";
            this.SendTo.Size = new System.Drawing.Size(75, 23);
            this.SendTo.TabIndex = 2;
            this.SendTo.Text = "发送";
            this.SendTo.UseVisualStyleBackColor = true;
            this.SendTo.Click += new System.EventHandler(this.SendTo_Click);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.SendTo);
            this.Controls.Add(this.SendMsg);
            this.Controls.Add(this.TextMsg);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private RichTextBox TextMsg;
        private TextBox SendMsg;
        private Button SendTo;
    }
}

执行代码:

using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Net.WebSockets;
using System.Text;

namespace ServerWinform
{

    public partial class Form1 : Form
    {
        private int localPort = 30081;

        private Socket socket;

        private Socket newSocket = null;

        private Thread th1;

        private Thread th2;
        public Form1()
        {
            InitializeComponent();
            Init();
        }

        private void Init()
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint localIPEndPoint = new IPEndPoint(IPAddress.Any, localPort);
            socket.Bind(localIPEndPoint);
            socket.Listen(20);
            th1 = new Thread(Listen);
            th1.IsBackground = true;
            th1.Start(socket);
        }

        private void OnChangeTextMsg(string msg)
        {
            this.TextMsg.AppendText(msg);
        }

        private void Listen(object o)
        {
            while (true)
            {
                newSocket = socket.Accept();
                string clientName = newSocket.RemoteEndPoint.ToString();

                this.Invoke(OnChangeTextMsg, $"\r\n{clientName} 连接成功");

                th2 = new Thread(ServerRecMsg);
                isReceive = true;
                th2.IsBackground = true;
                th2.Start(newSocket);
            }
        }

        private bool isReceive = true;
        private void ServerRecMsg(object o)
        {
            try
            {
                Socket newSocket = (Socket)o;
                while (isReceive)
                {
                    byte[] bytes = new byte[1024];
                    int byteLength = newSocket.Receive(bytes);
                    if (bytes.Length > 0)
                    {
                        string msg = Encoding.UTF8.GetString(bytes);
                        if (!string.IsNullOrEmpty(msg))
                        {
                            this.Invoke(OnChangeTextMsg, $"\r\n接收到客户端信息:{msg}");
                            if (msg == "close")
                            {
                                //客户端关闭
                                isReceive = false;
                                newSocket.Close();
                                this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                //客户端关闭
                isReceive = false;
                newSocket.Close();
                this.Invoke(OnChangeTextMsg, $"\r\n客户端关闭");
            }
        }

        private void TextMsg_TextChanged(object sender, EventArgs e)
        {
            this.TextMsg.SelectionStart = this.TextMsg.Text.Length;
            this.TextMsg.SelectionLength = 0;
            this.TextMsg.ScrollToCaret();
        }

        private void SendTo_Click(object sender, EventArgs e)
        {
            if (newSocket == null || !newSocket.Connected)
            {
                return;
            }
            string msg = this.SendMsg.Text;
            if (!string.IsNullOrEmpty(msg))
            {
                byte[] bytes = Encoding.UTF8.GetBytes(msg);
                newSocket.Send(bytes);
            }
            this.SendMsg.Text = "";
            this.Invoke(OnChangeTextMsg, $"\r\n发送给客户端信息:{msg}");
        }

        private void SendMsg_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SendTo_Click(sender, e);
            }
        }
    }
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值