简单设计窗体

Server.png

客户端代码

定义定义socket全局变量

Socket socketSend;

监听按钮事件

 private void button1_Click(object sender, EventArgs e)
        {
            //使用try...catch语句让服务器监听客户端
            try
            {
                //点击开始监听的时候,服务器创建一个负责侦听IP地址跟端口号的socket
                Socket socketwatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //Any提供一个 IP 地址,指示服务器应侦听所有网络接口上的客户端活动。此字段为只读。
                IPAddress ip = IPAddress.Any;
                //创建端口对象
                IPEndPoint point = new IPEndPoint(ip, 8500);
                //绑定
                socketwatch.Bind(point);
                showMsg("监听成功");
                // 将 System.Net.Sockets.Socket 置于侦听状态。 挂起连接队列的最大长度为10
                socketwatch.Listen(10);
                //创建一个线程
                Thread th=new Thread(Listen);
                //将线程至于后台运行
                th.IsBackground = true;
                //开始运行线程
                th.Start();

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }
        }

等待客户端的连接

 //等待客户端的连接
        void Listen(Object o)
        {
            try
            {
                //Object => 已知引用类型——使用as操作符完成
                Socket socketwatch = o as Socket;
                //一直等待连接
                while (true)
                {
                    //等待客户端的连接
                    socketSend = socketwatch.Accept();
                    showMsg(socketSend.RemoteEndPoint.ToString() + ":" + "连接成功!");
                    //开启一个新的线程不断接收客户端信息
                    Thread th = new Thread(Receive);
                    th.IsBackground = true;
                    th.Start(socketSend);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;
            }
        }

节接收客户端的消息

void Receive(Object o)
        {
            try
            {
                Socket socketSend = o as Socket;
                while (true)
                {
                    byte[] buffer = new byte[1024 * 1024 * 2];
                    int r = socketSend.Receive(buffer);
                    if (r == 0)
                    {
                        break;
                    }
                    string str = Encoding.UTF8.GetString(buffer, 0, r);
                    showMsg(socketSend.RemoteEndPoint + ":" + str);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                throw;

            }
        }

自定义打印函数

void showMsg(string s)
        {
            textBox1.AppendText(s + "\r\n");
        }

测试结果

测试结果.png

错误解决方案

目标机器积极拒绝,无法连接

  1. 查看端口号和ip地址是否正确
  2. 先启动服务端进行监听后启动客户端进行连接
  3. 重新启动解决方案

    线程间操作无效: 从不是创建控件 txtBOX 的线程访问它

  4. 在创建进程之前添加

    Control.CheckForIllegalCrossThreadCalls = false;

    简单的将错误提示禁用了,仍然存在跨线程调用控件的问题。为此可能造成两个线程同时或者循环改变该控件的状态导致线程死锁

  5. 使用委托,每个控件都有个InvokeRequired的属性,判断一下是不是true,是的话进行Invoke操作的
    例如:

     private delegate void ShowDelegate(string strshow);
       public void Show(string strshow)
       {
           if (this.txtreceive.InvokeRequired)
    
           {
            //   this.txtreceive.BeginInvoke(new ShowDelegate(Show), strshow);//这个也可以
               this.txtreceive.Invoke(new ShowDelegate(Show), strshow);
           }
           else
           {
                   this.txtreceive.Text += strshow;
    
           }
       }

    未将对象引用设置到对象的实例

  6. 线程未开启,,重新尝试开始线程

    参考解决方案

    https://blog.csdn.net/u011555996/article/details/53149368
    https://www.cnblogs.com/mechelle-olivia/p/7373153.html