C# UDP通信中UdpClient.Connect方法的必要性及同一主机下调用该方法导致无法接收响应的问题咨询
C# UDP通信中UdpClient.Connect方法的必要性及同一主机下调用该方法导致无法接收响应的问题咨询
大家好,这是我第一次提问,要是有信息没说全还请见谅~我刚接触C#里的UDP和套接字通信,现在卡在一个问题上了。
我现在想模拟一套UDP通信模型:实际场景里是电脑和一台托盘移动机通过UDP通信,不过机器还没到,没法真机测试,所以我写了两个独立的C#程序,分别模拟机器“服务端”和PC“客户端”来测试。
我的思路是:
- “服务端”机器先监听指定的IP地址和端口
- “客户端”PC向这个IP和端口发送数据包
- “服务端”收到数据包后,根据内容返回对应的响应
现在我遇到的核心问题是:**UdpClient.Connect(serverEP)这一行在UDP通信里是必须的吗?**我发现把这行注释掉的时候,客户端能正常收到服务端的响应;但要是保留这行代码,就收不到响应了。会不会是因为我用的是笔记本自己的IP来收发(服务端和客户端都在同一台机器上)导致的?
下面是我的两段代码:
模拟机器的服务端代码
private int UdpListenPort; private string localRunningIP; private UdpClient udpServer; private bool isListening = false; private Thread listenThread; private int port; private void Form1_Load(object sender, EventArgs e) { UdpListenPort = Int32.Parse("11000"); // 获取运行服务端的机器IP using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0)) { socket.Connect("8.8.8.8", 65530); IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint; localRunningIP = endPoint.Address.ToString(); } IPAddTB.Text = localRunningIP; PortNoTB.Text = UdpListenPort.ToString(); } private void StartBttn_Click(object sender, EventArgs e) { if (isListening) return; port = Int32.Parse(PortNoTB.Text); udpServer = new UdpClient(port); isListening = true; listenThread = new Thread(ListenForMessages); listenThread.IsBackground = true; listenThread.Start(); serverLogLB.Items.Add($"[Server] Started on port {port}..."); } private void ListenForMessages() { IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, port); try { while (isListening) { byte[] data = udpServer.Receive(ref remoteEP); string msg = Encoding.UTF8.GetString(data); Invoke((MethodInvoker)(() => serverLogLB.Items.Add($"[From {remoteEP}] {msg}"))); // 根据收到的消息返回对应响应 string response = handleMessages(msg); // 回复客户端 byte[] responseData = Encoding.UTF8.GetBytes(response); udpServer.Send(responseData, responseData.Length, remoteEP); } } catch (Exception ex) { if (isListening) Invoke((MethodInvoker)(() => serverLogLB.Items.Add($"[Error] {ex.Message}"))); serverLogLB.TopIndex = serverLogLB.Items.Count - 1; } } // 消息处理逻辑示例 private string handleMessages(string msg) { switch(msg) { case "MoveLeft": return "Left movement initiated"; case "MoveRight": return "Right movement initiated"; default: return "Unknown command"; } }
模拟PC的客户端代码
private UdpClient udpClient; private IPEndPoint serverEP; private bool isConnected = false; private bool connectToServer() { if (isConnected) return true; try { string ip = IPAddTB.Text; int port = int.Parse(PortNoTB.Text); udpClient = new UdpClient(); serverEP = new IPEndPoint(IPAddress.Parse(ip), port); // 注释这行就能收到响应,打开就收不到 //udpClient.Connect(serverEP); } catch (Exception ex) { serverLogLB.Items.Add("Failed to connect to server at:"); serverLogLB.Items.Add($"{IPAddTB.Text}, using port: {PortNoTB.Text}"); return false; } isConnected = true; return true; } private string SendMessage(string message) { logsTB.AppendText($"Trying to send message: {message}\n"); byte[] data = Encoding.UTF8.GetBytes(message); udpClient.Send(data, data.Length, serverEP); logsTB.AppendText($"[Client] Sent: {message}\n"); // 设置接收超时 udpClient.Client.ReceiveTimeout = 2000; try { IPEndPoint remoteEP = null; byte[] response = udpClient.Receive(ref remoteEP); string responseMsg = Encoding.UTF8.GetString(response); logsTB.AppendText($"Received Message: {responseMsg}\n"); return responseMsg; } catch (Exception ex) { logsTB.AppendText($"[Client] No response: {ex.Message}\n"); logsTB.ScrollToCaret(); return "Error or Unknown function code"; } }
后来我查了UdpClient.Connect方法的备注说明,了解到这个方法其实不是必须的——因为Send方法本身也可以指定端点参数,所以不用Connect也能正常收发消息。但我还是搞不懂:为什么在同一台主机上测试时,加上Connect就收不到服务端的响应了?实在没法可视化这个通信过程到底哪里出了问题,希望大家能帮忙解答一下~
内容来源于stack exchange
相关产品推荐
相关产品推荐

