您的当前位置:首页正文

UDP通讯 winform成功; WPF界面接收无响应,假死,并且服务器和客户端互相接收不到消息

2024-11-09 来源:个人技术集锦

UDP通讯 winform成功; WPF界面接收卡死,并且客户端接收不到

用winform做的界面客户端和服务器端可以成功接收和显示

服务器端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace comunication
{
public partial class Form1 : Form
{
//bool IsUDPStart = false;
Thread thread;
public Form1()
{
InitializeComponent();
}

    private void button1_Click(object sender, EventArgs e)
    {
       
            thread = new Thread(ServerMethod);//创建线程
            thread.Start();
            textBox1.Text = "服务器已启动";             
    }

    private void ServerMethod()
    {
        int recv;  //接收到的字符数
        byte[] revData = new byte[1024];  //接受缓存区
        byte[] sendData = new byte[1024];  //发送缓存区
        IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);  //本地IP
        EndPoint remote = (EndPoint)(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9998));  //远程IP
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //创建套接字
        try
        {
            sock.Bind(ip);  //绑定IP
            while (true)
            {
                recv = sock.ReceiveFrom(revData, ref remote);
                string type = Encoding.Unicode.GetString(revData, 0, recv);
                textBox2.Text = type;
                //发送信息
                sendData = Encoding.Unicode.GetBytes(textBox3.Text);

                sock.SendTo(sendData, sendData.Length, SocketFlags.None, remote);
            }
        }
        catch
        {
            sock.Close();
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        thread.Abort();
        textBox1.Text = "服务器已关闭";
    }
}

}

客户端
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace comunication
{
public partial class Form1 : Form
{
//bool IsUDPStart = false;
Thread thread;
public Form1()
{
InitializeComponent();
}

    private void button1_Click(object sender, EventArgs e)
    {
       
            thread = new Thread(ServerMethod);//创建线程
            thread.Start();
            textBox1.Text = "服务器已启动";
           
        
      
    }

    private void ServerMethod()
    {
        int recv;  //接收到的字符数
        byte[] revData = new byte[1024];  //接受缓存区
        byte[] sendData = new byte[1024];  //发送缓存区
        IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);  //本地IP
        EndPoint remote = (EndPoint)(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9998));  //远程IP
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //创建套接字
        try
        {
            sock.Bind(ip);  //绑定IP
            while (true)
            {
                recv = sock.ReceiveFrom(revData, ref remote);
                string type = Encoding.Unicode.GetString(revData, 0, recv);
                textBox2.Text = type;
                //发送信息
                sendData = Encoding.Unicode.GetBytes(textBox3.Text);

                sock.SendTo(sendData, sendData.Length, SocketFlags.None, remote);
            }
        }
        catch
        {
            sock.Close();
        }
    }

    private void button2_Click(object sender, EventArgs e)
    {
        thread.Abort();
        textBox1.Text = "服务器已关闭";
    }
}

}

wpf代码和winform中一样,但是在运行时会出现

下面图中所示,界面卡死。并且服务器端接收不到客户端发送的消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace 连接
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

        }

        //与服务器通信,获取所需信息
        private string ReadServer(string name)
        {
            string retValue = "";
            int recv;  //接收到的字符数
            byte[] revData = new byte[1024];  //接受缓存区
            byte[] sendData = new byte[1024];  //发送缓存区
            IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9998);  //本地IP和端口
            EndPoint Remote = (EndPoint)(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999));  //远程IP和端口
            Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //创建套接字
            try
            {
                sock.Bind(ip);  //绑定IP

                //发送请求
                sendData = Encoding.Unicode.GetBytes(name);
                sock.SendTo(sendData, sendData.Length, SocketFlags.None, Remote);

                //接受数据并转换成相应的类型    
                    recv = sock.ReceiveFrom(revData, ref Remote);
                    retValue = Encoding.Unicode.GetString(revData);

            }
            catch
            {
                sock.Close();
            }

            //关闭套接字
            sock.Close();
            return retValue;
        }

        private void send_click(object sender, RoutedEventArgs e)
        {
           txtReceive.Text = ReadServer(txtSend.Text);

        }

      
    }
}

服务器端 控件同上
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Server
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
Thread thread;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void ServerMethod()
    {
        int recv;  //接收到的字符数
        byte[] revData = new byte[1024];  //接受缓存区
        byte[] sendData = new byte[1024];  //发送缓存区
        IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999);  //本地IP
        EndPoint remote = (EndPoint)(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9998));  //远程IP
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);  //创建套接字
        try
        {
            sock.Bind(ip);  //绑定IP
            while (true)
            {
                recv = sock.ReceiveFrom(revData, ref remote);
                string type = Encoding.Unicode.GetString(revData, 0, recv);
                this.Dispatcher.Invoke(new Action(() =>
                {
                    txtReceive.Text = type;
                }));
                Thread.Sleep(500);

                this.Dispatcher.Invoke(new Action(() =>
                    {
                        //发送信息
                        sendData = Encoding.Unicode.GetBytes(txtSend.Text);
                        sock.SendTo(sendData, sendData.Length, SocketFlags.None, remote);
                    }));
                Thread.Sleep(500);


            }
        }
        catch
        {
            sock.Close();
        }
    }

    private void btn_start_click(object sender, RoutedEventArgs e)
    {
        txtfuwuqi.Text = "服务器已启动";
        //将问题代码块放入此函数中
        thread = new Thread(ServerMethod);//创建线程
        //thread.IsBackground = true;
        thread.Start();
        Thread.Sleep(500);
}

}
分析在做wpf实现UDP过程中出现的问题:
1、互相接收不到对方发送的消息
2、界面假死
第一个问题:
因为没有在Server程序中加入委托,导致UI界面中的控件无法和后台交互,在服务器代码中加入委托即可:

					this.Dispatcher.Invoke(new Action(() =>
                    {
                        txtReceive.Text = type;
                    }));
                    Thread.Sleep(500);

                    this.Dispatcher.Invoke(new Action(() =>
                        {
                            //发送信息
                            sendData = Encoding.Unicode.GetBytes(txtSend.Text);
                            sock.SendTo(sendData, sendData.Length, SocketFlags.None, remote);
                        }));
                    Thread.Sleep(500);

第二个问题:
界面无响应,如上图中所示,这时的服务器端可以接收到客户端的消息。但是如果输入消息,界面就会卡死。
因此将服务器中的代码

                    this.Dispatcher.Invoke(new Action(() =>
                    {
                    recv = sock.ReceiveFrom(revData, ref remote);
                    string type = Encoding.Unicode.GetString(revData, 0, recv);
                        txtReceive.Text = type;
                    }));

修改成

 					 recv = sock.ReceiveFrom(revData, ref remote);
                    string type = Encoding.Unicode.GetString(revData, 0, recv);
                    this.Dispatcher.Invoke(new Action(() =>
                    {
                        txtReceive.Text = type;
                    }));

即可,不知道什么原因,试出来的。如果哪位仁兄愿意指导指导,请赐教

Top