【发布时间】:2020-02-09 17:41:54
【问题描述】:
我在使用 Windows 中的 UDP 套接字时遇到问题。我有一个单独的应用程序,我正在尝试与端口 1625 上的输出通信并在端口 26027 上接收。我尝试制作一个简单的可执行文件来读取一条消息并发送一条消息。读取工作正常,但发送结束时出现 WSAEADDRNOTAVAIL (10049) 错误。
为了排除故障,我还在同一台机器上尝试了 Linux 中的等效代码(使用适用于 Linux 的 Windows 子系统),它运行良好。所以我无法弄清楚问题是什么。我也尝试禁用 Windows 防火墙,但这并没有什么不同。任何建议将不胜感激。
Windows Visual C++ 代码:
#pragma comment(lib, "Ws2_32.lib")
#include <iostream>
#include <WS2tcpip.h>
#define MAXLINE 1024
int main()
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
// Define local port address.
sockaddr_in local_port;
memset(&local_port, 0, sizeof(local_port));
local_port.sin_family = AF_INET;
local_port.sin_addr.s_addr = INADDR_ANY;
local_port.sin_port = htons(1625);
// Bind local socket.
int socket_id = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind(socket_id, (const struct sockaddr *)&local_port, sizeof(local_port));
// Receive UDP Port message.
char in_buffer[MAXLINE];
int num_bytes = recv(socket_id, (char *)in_buffer, MAXLINE, 0);
in_buffer[num_bytes] = '\0';
printf("Received : %s\n", in_buffer);
// Set up send destination port.
sockaddr_in dest_port;
memset(&dest_port, 0, sizeof(dest_port));
dest_port.sin_family = AF_INET;
dest_port.sin_addr.s_addr = INADDR_ANY;
dest_port.sin_port = htons(26027);
// Send UDP message to specific UDP port.
char out_buffer[] = "Test message";
int result = sendto(
socket_id, out_buffer, strlen(out_buffer), 0, (struct sockaddr *)&dest_port, sizeof(dest_port));
printf("Send result : %d -- WSA Error : %d\n", result, WSAGetLastError());
closesocket(socket_id);
return 0;
}
运行此可执行文件的终端输出是:
Received : 5e4009df*755=-0.0028:761=0.6942
Send result : -1 -- WSA Error : 10049
WSL linux C++ 代码(相同的源代码,除了 WSA 包含和错误输出):
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define MAXLINE 1024
int main()
{
// Define local port address.
sockaddr_in local_port;
memset(&local_port, 0, sizeof(local_port));
local_port.sin_family = AF_INET;
local_port.sin_addr.s_addr = INADDR_ANY;
local_port.sin_port = htons(1625);
// Bind local socket.
int socket_id = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind(socket_id, (const struct sockaddr *)&local_port, sizeof(local_port));
// Receive UDP Port message.
char in_buffer[MAXLINE];
int num_bytes = recv(socket_id, (char *)in_buffer, MAXLINE, 0);
in_buffer[num_bytes] = '\0';
printf("Received : %s\n", in_buffer);
// Set up send destination port.
sockaddr_in dest_port;
memset(&dest_port, 0, sizeof(dest_port));
dest_port.sin_family = AF_INET;
dest_port.sin_addr.s_addr = INADDR_ANY;
dest_port.sin_port = htons(26027);
// Send UDP message to specific UDP port.
char out_buffer[] = "Test message";
int result = sendto(
socket_id, out_buffer, strlen(out_buffer), 0, (struct sockaddr *) &dest_port, sizeof(dest_port));
printf("Send result : %d\n", result);
close(socket_id);
return 0;
}
运行此可执行文件的终端输出是:
Received : 5e4009df*755=-0.0028:761=0.6942
Send result : 12
我还可以验证通过此 Linux 实现到端口 26027 的输出是否已被其他应用程序接收,并且还可以在 Wireshark 中看到它。
编辑:
在下面 Remy 的回答之后,我能够按照下面的 cmets 来完成这项工作。澄清我的网络:
如果我使用 Wireshark 查看我的网络现在看起来像:
127.0.0.1 UDP 50223 → 1625 Len=32
127.0.0.1 UDP 1625 → 26027 Len=12
我的节点绑定到 1625,它可以从某个未知端口号(本例中为 50223)recv()UDP 和 sendto() 端口 26027 绑定。
【问题讨论】: