C# Socket通信线程封锁操作

发布于 2022-09-04 10:29:22 字数 4847 浏览 41 评论 0

我想实现两端之间的通信
clipboard.png

客户端发送消息给服务端是没有问题的,但是服务端发送消息给服务端的消息会出现错误。

报错信息如下:
clipboard.png

服务端代码:

Socket socketWatch;

        //单击监听开始初始化
        private void btnconect_Click(object sender, EventArgs e)
        {
            
            try
            {  //其中,addressFamily 参数指定 Socket 使用的寻址方案,socketType 参数指定 Socket 的类型,protocolType 参数指定 Socket 使用的协议
                socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                //获取IP
                IPAddress ip = IPAddress.Parse(txtIP.Text);

                //将ip与端口绑定起来,获取远程服务器的终结点
                IPEndPoint ipend = new IPEndPoint(ip, int.Parse(txtpoint.Text));
                //绑定关联服务器的ip与端口
                socketWatch.Bind(ipend);
                //开始监听()
                socketWatch.Listen(10);
                txtStatuss.AppendText("监听成功!\n");

                //创建一个线程,在后台中不断地循环等待接收新的客户端的连接
                Thread th = new Thread(accept);
                th.IsBackground = true;
                th.Start(socketWatch);
            }
            catch {
                MessageBox.Show("IPV4地址或者端口号有不正确!");
            }


        }
        Dictionary<string, Socket> dirlist = new Dictionary<string, Socket>();

        //等待客户端的连接
        Socket listen;
        void accept(object o)
        {
           
                while (true)
                {
               Socket Listen = o as Socket;
              listen= Listen.Accept();
                
                txtStatuss.AppendText(listen.RemoteEndPoint.ToString() + ":" + "连接成功!!\n");
                    //txtStatuss.AppendText(listen.RemoteEndPoint.ToString() + ": 连接成功!!");
                    //将连接到的客户端的IP地址添加到combox当中,以便后面添加新功能(选定某个联系人发送消息)
                    comContatics.Items.Add(listen.RemoteEndPoint.ToString());
                    //将添加到的客户端的IP地址添加到dirlist泛型集合当中以后后面添加新功能(指定给某个联系给发送消息)
                    dirlist.Add(listen.RemoteEndPoint.ToString(), listen);

                    //创建一个线程,在后台不断地循环接收客户端发送过来的消息
                    Thread th = new Thread(recive);
                    th.IsBackground = true;
                    th.Start(listen);
                }

            }
        Socket recives;
        //接收客户端发送过来的数据
        void recive(object o)
        {
            recives = o as Socket;
            byte[] buffer = new byte[1024 * 1024 * 5];

            //接收到的字节数
           int r= recives.Receive(buffer);

            //将接收到的字节数进行解码
          txtStatuss.AppendText( recives.RemoteEndPoint.ToString()+" : "+ Encoding.UTF8.GetString(buffer,0,r)+"\n");
        }
        //窗体加载
        private void Service_Load(object sender, EventArgs e)
        {
            //取消跨线程之间的检查
            Control.CheckForIllegalCrossThreadCalls = false;

            //创建一个线程,后台不断地检测计算机是否有网络
            Thread th = new Thread(TestWeb);
            th.IsBackground = true;
            th.Start();
        }

客户端部分代码如下:

Socket con;
        private void Conect_Click(object sender, EventArgs e)
        {
           
                con = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

                //获取IP地址
                IPAddress ip = IPAddress.Parse(txtIP.Text);
                //获取端口号
                int point = int.Parse(TxtPoint.Text);

                con.Connect(ip, point);

                txtStatus.AppendText("与" + con.RemoteEndPoint.ToString() + "连接成功!!");
            
             

            //在后台不断地循环等待服务端发送过来的消息
            Thread th = new Thread(Recive);
            th.IsBackground = true;
            th.Start();
        }

        //接收数据
       // Socket recive;
        //需要将接收到的二进制进行转换成我们需要的字符
        void Recive()
        {
            while (true)
            {
                byte[] buffer = new byte[1024 * 1024 * 5];
                //接收到的字节数
                int r = con.Receive(buffer);
                if (r == 0)
                {
                    break;
                }
                //将接收到的字节数开始解码
                txtStatus.AppendText(Encoding.UTF8.GetString(buffer, 0, r) + "\n");
            }
           
        }
        //单击发送按钮发送消息
        private void ClientSend_Click(object sender, EventArgs e)
        {
            try
            {
                //将要发送的消息转换成二进制字节类型进行传输
                con.Send(Encoding.UTF8.GetBytes(txtNews.Text.Trim()));
                con.Close();

            }
            catch {
                MessageBox.Show("网络未知错误!");
            }
            
        }

请教一下各位大神问题在哪里,困扰我一天了。。非常感谢。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

天涯沦落人 2022-09-11 10:29:22
  1. 服务端的recive函数应该是循环不断接收的

  2. 客户端的ClientSend_Click在发送数据之后,就调用con.Close();关闭了,服务端再发送当然发不过去了。

另外跨线程能不关检查就不要关检查,多写行invoke处理一下吧

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文