C# WebSocket通讯 转发mqtt信息

目录

0 任务概述

1 WebSocket & mqtt是什么

2 代码实现

1. WebSocket客户端:

2. WebSocket服务端

3 其他参考


0 任务概述

如前所述,WebSocket通讯实现C++/C#_Suxiang997的博客-CSDN博客

目标:假定有一条来自mqtt的信息,将这条信息转发至WebSocket服务器端。

最终效果:A主机是WebSocket客户端,兼具mqtt发布者/订阅者的功能,作为发布者自定义消息发送至mqtt云端服务器B,再由云端回响给订阅者A,最后转发至另一台电脑C的WebSocket服务端。

C# WebSocket通讯 转发mqtt信息_第1张图片 WebSocket服务端

C# WebSocket通讯 转发mqtt信息_第2张图片 WebSocket&mqtt客户端

1 WebSocket & mqtt是什么

1> MQTT

MQTT协议,终于有人讲清楚了_小麦大叔的博客-CSDN博客

基于发布/订阅publish/subscribe)模式的“轻量级”通讯协议,该协议构建于TCP/IP协议上

MQTT最大优点在于,用极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务

低开销、低带宽占用的即时通讯协议

2> WebSocket

WebSocket_ohana!的博客-CSDN博客

WebSocket详解:技术原理、代码演示和应用案例 - 知乎 (zhihu.com)

  • WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样;
  • WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。

ubuntu C# 和windows C# socket TCP通信(附用emqx开启mqtt服务器)_ubuntu与windows通信_Suxiang997的博客-CSDN博客

2 代码实现

参考:C# Socket网络编程入门(服务器与客户端通信,客户端与客户端通信)_c#客户端和客户端通信_黄瓜炒鸡蛋儿的博客-CSDN博客

1. WebSocket客户端:

 Program.cs:主程序,入口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WS_C_2_WindowsFormsApp1
{
    static class Program
    {
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new ClientForm());
        }
    }
}

ClientForm.Designer.cs:Form文件设计


namespace WS_C_2_WindowsFormsApp1
{
    partial class ClientForm
    {
        /// 
        /// 必需的设计器变量。
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// 清理所有正在使用的资源。
        /// 
        /// 如果应释放托管资源,为 true;否则为 false。
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// 
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// 
        private void InitializeComponent()
        {
            this.btn_Link = new System.Windows.Forms.Button();
            this.lab_Port = new System.Windows.Forms.TextBox();
            this.lab_Ip = new System.Windows.Forms.TextBox();
            this.Port = new System.Windows.Forms.Label();
            this.label1 = new System.Windows.Forms.Label();
            this.txt_Cont = new System.Windows.Forms.TextBox();
            this.txt_Msg = new System.Windows.Forms.TextBox();
            this.btn_Send = new System.Windows.Forms.Button();
            this.label2 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // btn_Link
            // 
            this.btn_Link.Location = new System.Drawing.Point(552, 59);
            this.btn_Link.Name = "btn_Link";
            this.btn_Link.Size = new System.Drawing.Size(176, 23);
            this.btn_Link.TabIndex = 0;
            this.btn_Link.Text = "Link";
            this.btn_Link.UseVisualStyleBackColor = true;
            this.btn_Link.Click += new System.EventHandler(this.btn_Link_Click);
            // 
            // lab_Port
            // 
            this.lab_Port.Location = new System.Drawing.Point(359, 59);
            this.lab_Port.Name = "lab_Port";
            this.lab_Port.Size = new System.Drawing.Size(100, 21);
            this.lab_Port.TabIndex = 1;
            this.lab_Port.Text = "2000";
            // 
            // lab_Ip
            // 
            this.lab_Ip.Location = new System.Drawing.Point(104, 59);
            this.lab_Ip.Name = "lab_Ip";
            this.lab_Ip.Size = new System.Drawing.Size(100, 21);
            this.lab_Ip.TabIndex = 2;
            this.lab_Ip.Text = "192.168.0.111";
            this.lab_Ip.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
            // 
            // Port
            // 
            this.Port.AutoSize = true;
            this.Port.Location = new System.Drawing.Point(312, 64);
            this.Port.Name = "Port";
            this.Port.Size = new System.Drawing.Size(41, 12);
            this.Port.TabIndex = 3;
            this.Port.Text = "Port:";
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(69, 62);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(29, 12);
            this.label1.TabIndex = 4;
            this.label1.Text = "IP:";
            // 
            // txt_Cont
            // 
            this.txt_Cont.Location = new System.Drawing.Point(71, 107);
            this.txt_Cont.Multiline = true;
            this.txt_Cont.Name = "txt_Cont";
            this.txt_Cont.Size = new System.Drawing.Size(657, 243);
            this.txt_Cont.TabIndex = 5;
            this.txt_Cont.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
            // 
            // txt_Msg
            // 
            this.txt_Msg.Location = new System.Drawing.Point(71, 358);
            this.txt_Msg.Name = "txt_Msg";
            this.txt_Msg.Size = new System.Drawing.Size(552, 21);
            this.txt_Msg.TabIndex = 6;
            // 
            // btn_Send
            // 
            this.btn_Send.Location = new System.Drawing.Point(629, 356);
            this.btn_Send.Name = "btn_Send";
            this.btn_Send.Size = new System.Drawing.Size(99, 23);
            this.btn_Send.TabIndex = 7;
            this.btn_Send.Text = "Send";
            this.btn_Send.UseVisualStyleBackColor = true;
            this.btn_Send.Click += new System.EventHandler(this.btn_Send_Click);
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Font = new System.Drawing.Font("宋体", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
            this.label2.Location = new System.Drawing.Point(68, 88);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(48, 16);
            this.label2.TabIndex = 8;
            this.label2.Text = "Panel";
            this.label2.Click += new System.EventHandler(this.label2_Click);
            // 
            // ClientForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.btn_Send);
            this.Controls.Add(this.txt_Msg);
            this.Controls.Add(this.txt_Cont);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.Port);
            this.Controls.Add(this.lab_Ip);
            this.Controls.Add(this.lab_Port);
            this.Controls.Add(this.btn_Link);
            this.Name = "ClientForm";
            this.Text = "Client";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btn_Link;
        private System.Windows.Forms.TextBox lab_Port;
        private System.Windows.Forms.TextBox lab_Ip;
        private System.Windows.Forms.Label Port;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.TextBox txt_Cont;
        private System.Windows.Forms.TextBox txt_Msg;
        private System.Windows.Forms.Button btn_Send;
        private System.Windows.Forms.Label label2;
    }
}

ClientForm.cs:客户端实现(集成mqtt Publish&Subscriber的功能)

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;
using uPLibrary.Networking.M2Mqtt;
using uPLibrary.Networking.M2Mqtt.Messages;

namespace WS_C_2_WindowsFormsApp1
{
    public partial class ClientForm : Form
    {
        public ClientForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //csharpMQTT.CS_mqtt mqttClient = new csharpMQTT.CS_mqtt();
        }

        Socket socketSend;

        //点击连接
        private void btn_Link_Click(object sender, EventArgs e)
        {
            try
            {
                _ = CS_mqtt_Main();
                //创建负责通信的Socket
                socketSend = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                IPAddress ip = IPAddress.Parse(lab_Ip.Text);
                IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32(lab_Port.Text));
                //IPAddress ip = IPAddress.Parse("192.168.0.105");
                //IPEndPoint point = new IPEndPoint(ip, Convert.ToInt32("2000"));
                socketSend.Connect(point);

                ShowMsg("连接成功,目标服务器IP地址为:" + ip.ToString());

                //开启一个线程不停接受服务器发送来的信息
                Thread th = new Thread(Recive)
                {
                    IsBackground = true
                };
                th.Start();
            }
            catch (Exception ex)
            {
                //处理异常
                ShowMsg("连接失败:" + ex.Message);
            }
        }

        //不停接受服务器发来的消息
        void Recive()
        {
            while (true)
            {
                byte[] buffer = new byte[1024 * 1024 * 3];
                //实际接受到的有效字节
                int r = socketSend.Receive(buffer);

                if (r <= 0)
                {
                    break;
                }

                string s = Encoding.UTF8.GetString(buffer, 0, r);

                ShowMsg(socketSend.RemoteEndPoint + ":" + s);
            }
        }


        void ShowMsg(string str)
        {
            //txt_Cont.AppendText(str + "\r\n");
            if (txt_Cont.InvokeRequired)
            {
                txt_Cont.Invoke(new Action(ShowMsg), str);
            }
            else
            {
                txt_Cont.AppendText(str + "\r\n");
            }
        }

        //点击发送按钮,客户端给服务器发送消息
        private void btn_Send_Click(object sender, EventArgs e)
        {
            string str = txt_Msg.Text.Trim();
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            socketSend.Send(buffer);
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void Port_Click(object sender, EventArgs e)
        {

        }

        //mqtt部分
        MqttClient ConnectMQTT(string broker, int port, string clientId, string username, string password)
        {
            MqttClient client = new MqttClient(broker, port, false, MqttSslProtocols.None, null, null);
            client.Connect(clientId, username, password);
            if (client.IsConnected)
            {
                ShowMsg("Connected to MQTT Broker");
            }
            else
            {
                ShowMsg("Failed to connect");
            }
            return client;
        }

        void Publish(MqttClient client, string topic)
        {
            int msg_count = 0;
            while (true)
            {
                System.Threading.Thread.Sleep(1 * 1000);
                string msg = "messages: " + msg_count.ToString();
                client.Publish(topic, System.Text.Encoding.UTF8.GetBytes(msg));
                ShowMsg("Send '" + msg + "' to topic '" + topic + "'");
                //Console.WriteLine("Send `{0}` to topic `{1}`", msg, topic);
                msg_count++;
            }
        }

        void Subscribe(MqttClient client, string topic)
        {
            client.MqttMsgPublishReceived += client_MqttMsgPublishReceived;
            client.Subscribe(new string[] { topic }, new byte[] { MqttMsgBase.QOS_LEVEL_AT_MOST_ONCE });
        }
        void client_MqttMsgPublishReceived(object sender, MqttMsgPublishEventArgs e)
        {
            string payload = Encoding.Default.GetString(e.Message);
            ShowMsg("Received '" + payload + "' from '" + e.Topic.ToString() + "' topic");
            //Console.WriteLine("Received `{0}` from `{1}` topic", payload, e.Topic.ToString());

            //将从mqtt服务端获取到的数据再转发给ws服务端
            Transmit(Encoding.Default.GetString(e.Message));
        }
        /// 
        /// 将从mqtt服务端获取到的数据再转发给ws服务端
        /// 
        void Transmit(string msg)
        {
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(msg);
            socketSend.Send(buffer);
        }

        /// 
        /// Mqtt服务器连接的入口,完成client对象创建等功能
        /// 
        //static void Main(string[] args)
        async Task CS_mqtt_Main()
        {
            string broker = "broker.emqx.io";//服务器地址,默认为云端服务器
            //string broker = "115.156.168.35"; //本地服务器ip
            int port = 1883;
            string topic = "Csharp/mqtt";
            string clientId = Guid.NewGuid().ToString();
            string username = "emqx";
            string password = "public";
            MqttClient client = ConnectMQTT(broker, port, clientId, username, password);
            Subscribe(client, topic);
            //异步方法,它不会阻塞当前线程。相反,它会返回一个Task对象,表示指定的时间过去后,操作将完成。在等待这个Task对象完成的过程中,线程可以执行其他操作。这使得程序更加响应,因为用户可以与程序进行交互,而不必等待Task.Delay返回。
            var cancellationTokenSource = new CancellationTokenSource();
            var publishTask = Task.Run(() => Publish(client, topic), cancellationTokenSource.Token);
            await publishTask;
            //Publish(client, topic);
        }


    }
}

2. WebSocket服务端

Program.cs:主程序,入口

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using WS_S_2_WindowsFormsApp1;

namespace WS_C_2_WindowsFormsApp1
{
    static class Program
    {
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new ServerForm());
        }
    }
}

Server.cs :功能实现区

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 WS_S_2_WindowsFormsApp1
{
    public partial class ServerForm : Form
    {
        List ClientProxSocketList = new List();

        public ServerForm()
        {
            InitializeComponent();
        }

        Socket proxSocket;


        //点击启动按钮
        private void btn_Start_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(txt_Ip.Text), int.Parse(txt_Port.Text)));

            //3 开启监听
            socket.Listen(1000);  //连接:最大接收请求数,超出返回错误信息

            //4 开始接收客户端的连接
            ThreadPool.QueueUserWorkItem(new WaitCallback(this.AcceptClientConnect), socket);


        }


        //将远程连接的客户端的IP地址和Socket存入集合中
        Dictionary dicSocket = new Dictionary();

        public void AcceptClientConnect(object socket)
        {
            var serverSocket = socket as Socket;

            this.AppendTextToTxtLog("服务器开始接受客户端的连接。");

            while (true)
            {
                //负责跟客户通信的Socket
                proxSocket = serverSocket.Accept();
                //将远程连接的客户端的IP地址和Socket存入集合中
                dicSocket.Add(proxSocket.RemoteEndPoint.ToString(), proxSocket);
                //将远程连接的客户端IP地址和端口存储下拉框中
                //cboUsers.Items.Add(proxSocket.RemoteEndPoint.ToString());

                this.AppendTextToTxtLog(string.Format("客户端:{0}连接上了", proxSocket.RemoteEndPoint.ToString()));

                ClientProxSocketList.Add(proxSocket);

                //不停的接收当前连接的客户端发送的信息
                // proxSocket.Receive();

                ThreadPool.QueueUserWorkItem(new WaitCallback(ReceiveData), proxSocket);
            }

        }


        //接收客户端的消息
        public void ReceiveData(object socket)
        {
            var proxSocket = socket as Socket;
            byte[] data = new byte[1024 * 1024 * 2];
            while (true)
            {

                int len = 0;

                try
                {
                    len = proxSocket.Receive(data, 0, data.Length, SocketFlags.None);
                }
                catch (Exception)
                {
                    //异常退出
                    AppendTextToTxtLog(string.Format("客户端:{0}正常退出", proxSocket.RemoteEndPoint.ToString()));
                    ClientProxSocketList.Remove(proxSocket);
                    return;
                }



                if (len <= 0)
                {
                    //客户端正常退出
                    AppendTextToTxtLog(string.Format("客户端:{0}正常退出", proxSocket.RemoteEndPoint.ToString()));

                    ClientProxSocketList.Remove(proxSocket);
                    return;//让方法结束,终结当前接受客户端数据的异步线程
                }

                //把接收到的数据放到文本框中
                string str = Encoding.UTF8.GetString(data, 0, len);
                AppendTextToTxtLog(string.Format("接收到客户端:{0}的消息是:{1}", proxSocket.RemoteEndPoint.ToString(), str));

                //服务器转发信息,除发送方以外,转发信息
                //先不需要此功能,客户端A第一次进入时编号1,退出再进编号2;但是1 2 都会被存入队列,服务端转发信息给所有客户端时,会找不到1
                //byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
                //foreach (var item in dicSocket)
                //{
                //    if (item.Key != proxSocket.RemoteEndPoint.ToString())
                //        item.Value.Send(buffer);
                //}

                //服务器给发送者回响消息,没写好
                //byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
                //foreach (var item in dicSocket)
                //{
                //    if (item.Key != proxSocket.RemoteEndPoint.ToString())
                //        item.Value.Send(buffer);
                //}

            }
        }

        //往日志的文本框上追加数据
        public void AppendTextToTxtLog(string txt)
        {
            if (txt_Cont.InvokeRequired)
            {
                txt_Cont.Invoke(new Action(s =>
                {
                    this.txt_Cont.Text = string.Format("{0}\r\n{1}", s, txt_Cont.Text);
                }), txt);
            }
            else
            {
                this.txt_Cont.Text = string.Format("{0}\r\n{1}", txt, txt_Cont.Text);
            }


        }


        //服务器给客户端发送信息
        private void btn_Send_Click(object sender, EventArgs e)
        {
            #region
            //foreach (var proxSocket in ClientProxSocketList)
            //{
            //    if (proxSocket.Connected)
            //    {
            //        byte[] data = Encoding.Default.GetBytes(txt_Msg.Text);
            //        proxSocket.Send(data, 0, data.Length, SocketFlags.None);
            //    }
            //}
            #endregion

            string str = txt_Msg.Text;
            byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
            //获取用户在下拉框中选择的IP地址
            //string ip = cboUsers.SelectedItem.ToString();





            foreach (var item in dicSocket)
            {
                //if(item.Key != proxSocket.RemoteEndPoint.ToString())
                item.Value.Send(buffer);
            }


            //proxSocket.Send(buffer);

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void label3_Click(object sender, EventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}

       Server.Designer.cs


namespace WS_S_2_WindowsFormsApp1
{
    partial class ServerForm
    {
        /// 
        /// 必需的设计器变量。
        /// 
        private System.ComponentModel.IContainer components = null;

        /// 
        /// 清理所有正在使用的资源。
        /// 
        /// 如果应释放托管资源,为 true;否则为 false。
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows 窗体设计器生成的代码

        /// 
        /// 设计器支持所需的方法 - 不要修改
        /// 使用代码编辑器修改此方法的内容。
        /// 
        private void InitializeComponent()
        {
            this.btn_Start = new System.Windows.Forms.Button();
            this.btn_Send = new System.Windows.Forms.Button();
            this.txt_Ip = new System.Windows.Forms.TextBox();
            this.txt_Port = new System.Windows.Forms.TextBox();
            this.txt_Cont = new System.Windows.Forms.TextBox();
            this.txt_Msg = new System.Windows.Forms.TextBox();
            this.label1 = new System.Windows.Forms.Label();
            this.label2 = new System.Windows.Forms.Label();
            this.SuspendLayout();
            // 
            // btn_Start
            // 
            this.btn_Start.Location = new System.Drawing.Point(539, 39);
            this.btn_Start.Name = "btn_Start";
            this.btn_Start.Size = new System.Drawing.Size(176, 23);
            this.btn_Start.TabIndex = 0;
            this.btn_Start.Text = "Start";
            this.btn_Start.UseVisualStyleBackColor = true;
            this.btn_Start.Click += new System.EventHandler(this.btn_Start_Click);
            // 
            // btn_Send
            // 
            this.btn_Send.Location = new System.Drawing.Point(640, 361);
            this.btn_Send.Name = "btn_Send";
            this.btn_Send.Size = new System.Drawing.Size(75, 23);
            this.btn_Send.TabIndex = 1;
            this.btn_Send.Text = "Send";
            this.btn_Send.UseVisualStyleBackColor = true;
            this.btn_Send.Click += new System.EventHandler(this.btn_Send_Click);
            // 
            // txt_Ip
            // 
            this.txt_Ip.Location = new System.Drawing.Point(120, 39);
            this.txt_Ip.Name = "txt_Ip";
            this.txt_Ip.Size = new System.Drawing.Size(100, 21);
            this.txt_Ip.TabIndex = 2;
            this.txt_Ip.Text = "192.168.0.105";
            // 
            // txt_Port
            // 
            this.txt_Port.ForeColor = System.Drawing.SystemColors.WindowText;
            this.txt_Port.Location = new System.Drawing.Point(377, 39);
            this.txt_Port.Name = "txt_Port";
            this.txt_Port.Size = new System.Drawing.Size(100, 21);
            this.txt_Port.TabIndex = 3;
            this.txt_Port.Text = "2000";
            // 
            // txt_Cont
            // 
            this.txt_Cont.Location = new System.Drawing.Point(84, 88);
            this.txt_Cont.Multiline = true;
            this.txt_Cont.Name = "txt_Cont";
            this.txt_Cont.Size = new System.Drawing.Size(631, 260);
            this.txt_Cont.TabIndex = 4;
            // 
            // txt_Msg
            // 
            this.txt_Msg.Location = new System.Drawing.Point(84, 363);
            this.txt_Msg.Name = "txt_Msg";
            this.txt_Msg.Size = new System.Drawing.Size(533, 21);
            this.txt_Msg.TabIndex = 5;
            // 
            // label1
            // 
            this.label1.AutoSize = true;
            this.label1.Location = new System.Drawing.Point(86, 43);
            this.label1.Name = "label1";
            this.label1.Size = new System.Drawing.Size(29, 12);
            this.label1.TabIndex = 6;
            this.label1.Text = "IP:";
            // 
            // label2
            // 
            this.label2.AutoSize = true;
            this.label2.Location = new System.Drawing.Point(330, 44);
            this.label2.Name = "label2";
            this.label2.Size = new System.Drawing.Size(41, 12);
            this.label2.TabIndex = 7;
            this.label2.Text = "Port:";
            // 
            // ServerForm
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(800, 450);
            this.Controls.Add(this.label2);
            this.Controls.Add(this.label1);
            this.Controls.Add(this.txt_Msg);
            this.Controls.Add(this.txt_Cont);
            this.Controls.Add(this.txt_Port);
            this.Controls.Add(this.txt_Ip);
            this.Controls.Add(this.btn_Send);
            this.Controls.Add(this.btn_Start);
            this.Name = "ServerForm";
            this.Text = "Server";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Button btn_Start;
        private System.Windows.Forms.Button btn_Send;
        private System.Windows.Forms.TextBox txt_Ip;
        private System.Windows.Forms.TextBox txt_Port;
        private System.Windows.Forms.TextBox txt_Cont;
        private System.Windows.Forms.TextBox txt_Msg;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Label label2;
    }
}

3 其他参考

如有遗漏,参见以前的遗弃版本:

WebSocket通讯实现C++/C#_Suxiang997的博客-CSDN博客

ubuntu C# 和windows C# socket TCP通信(附用emqx开启mqtt服务器)_ubuntu与windows通信_Suxiang997的博客-CSDN博客

你可能感兴趣的:(websocket,网络协议,网络)