Sendto 函数 return 错误 - windows 上的 UDP 套接字
Sendto function return error - UDP socket on windows
我的 sendto 功能有问题。我想从 UDP 服务器获取时间。我的代码是这样的:
unsigned char msg[48]={010,0,0,0,0,0,0,0,0};
char* hostname=(char *)"tick.usno.navy.mil";
sockaddr_in server_addr;
WSAData data;
int result=WSAStartup( MAKEWORD( 2, 2 ), &data );
if (result != NO_ERROR) {
printf("WSAStartup failed with error: %d\n", result);
return 1;
}
int client_s = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
if (client_s == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
unsigned short Port = 123;
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(Port); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
char out_buf[BUFFER_SIZE];
int retcode = sendto(client_s, reinterpret_cast<const char*>(msg), sizeof(msg), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
perror("sendto:");
if (retcode == SOCKET_ERROR) {
printf("sendto failed with error: %d\n", WSAGetLastError());
closesocket(client_s);
WSACleanup();
return 1;
}
我的输出是这样的:
sendto:: No error
sendto failed with error: 10013
当我尝试使用 recv 接收数据时,出现错误。我想使用 C++ 从 windows 上的 UDP 服务器获取时间。这里的问题在哪里?为什么一个错误说没有错误,一个错误说 10013,我该如何解决?
旧的答案(保留在下面)仅供参考,但对于这种情况不正确。
问题很有可能是这两行
char* hostname=(char *)"tick.usno.navy.mil";
...
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
inet_addr
函数需要一个点分十进制的 IPv4 地址。不是未解析的主机名。如果没有提供有效的 IPv4 点分十进制地址,该函数将 return INADDR_NONE
这不是有效地址,并且在使用地址时会导致问题,例如sendto
。会不会导致题中报错?老实说我不知道,但它肯定不会像预期的那样工作。
要将主机名解析为 IP 地址,您应该使用 getaddrinfo
。链接参考还包含有关如何使用它的示例。
错误 10013
是,如果您查看例如this Windows socket error reference WSAEACCESS
,存在一些权限问题。如果您稍微搜索一下,您会发现 1024
下的端口是为系统保留的,您需要提升权限才能使用它们。
如果您想创建一个 NTP 服务器或客户端,您需要 运行 您的程序使用提升的访问权限,例如使用 "Run as administrator".
至于留言
sendto:: No error
来自于perror
呼叫你sendto
后无条件呼叫。首先,在 Windows 上,套接字函数没有设置 perror
使用的 errno
。其次,如果之前对 errno
的调用实际上没有失败,则 errno
的状态是未定义的。
所以不要无条件地使用它,也不要将它用于Windows套接字功能。
我的 sendto 功能有问题。我想从 UDP 服务器获取时间。我的代码是这样的:
unsigned char msg[48]={010,0,0,0,0,0,0,0,0};
char* hostname=(char *)"tick.usno.navy.mil";
sockaddr_in server_addr;
WSAData data;
int result=WSAStartup( MAKEWORD( 2, 2 ), &data );
if (result != NO_ERROR) {
printf("WSAStartup failed with error: %d\n", result);
return 1;
}
int client_s = socket(AF_INET, SOCK_DGRAM,IPPROTO_UDP);
if (client_s == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
unsigned short Port = 123;
server_addr.sin_family = AF_INET; // Address family to use
server_addr.sin_port = htons(Port); // Port num to use
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
char out_buf[BUFFER_SIZE];
int retcode = sendto(client_s, reinterpret_cast<const char*>(msg), sizeof(msg), 0,(struct sockaddr *)&server_addr, sizeof(server_addr));
perror("sendto:");
if (retcode == SOCKET_ERROR) {
printf("sendto failed with error: %d\n", WSAGetLastError());
closesocket(client_s);
WSACleanup();
return 1;
}
我的输出是这样的:
sendto:: No error
sendto failed with error: 10013
当我尝试使用 recv 接收数据时,出现错误。我想使用 C++ 从 windows 上的 UDP 服务器获取时间。这里的问题在哪里?为什么一个错误说没有错误,一个错误说 10013,我该如何解决?
旧的答案(保留在下面)仅供参考,但对于这种情况不正确。
问题很有可能是这两行
char* hostname=(char *)"tick.usno.navy.mil";
...
server_addr.sin_addr.s_addr = inet_addr(hostname); // IP address to use
inet_addr
函数需要一个点分十进制的 IPv4 地址。不是未解析的主机名。如果没有提供有效的 IPv4 点分十进制地址,该函数将 return INADDR_NONE
这不是有效地址,并且在使用地址时会导致问题,例如sendto
。会不会导致题中报错?老实说我不知道,但它肯定不会像预期的那样工作。
要将主机名解析为 IP 地址,您应该使用 getaddrinfo
。链接参考还包含有关如何使用它的示例。
错误 10013
是,如果您查看例如this Windows socket error reference WSAEACCESS
,存在一些权限问题。如果您稍微搜索一下,您会发现 1024
下的端口是为系统保留的,您需要提升权限才能使用它们。
如果您想创建一个 NTP 服务器或客户端,您需要 运行 您的程序使用提升的访问权限,例如使用 "Run as administrator".
至于留言
sendto:: No error
来自于perror
呼叫你sendto
后无条件呼叫。首先,在 Windows 上,套接字函数没有设置 perror
使用的 errno
。其次,如果之前对 errno
的调用实际上没有失败,则 errno
的状态是未定义的。
所以不要无条件地使用它,也不要将它用于Windows套接字功能。