C语言 socket() 返回 -1 但 errno 0
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7962531/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
socket() return -1 but errno 0
提问by twfx
I tried to create a UDP socket on mingw, but socket()returns -1, with errno = 0. Strange.
I have included winsock2.h.
Initially I had compilation error undefined reference to socket@12, after setting
-lws2_32and -lwsock32to Linker Settings of Code::Block, compilation success.
我试图在 mingw 上创建一个 UDP 套接字,但socket()返回-1,带有 errno = 0。奇怪的。我已经包含了 winsock2.h。最初我有编译错误undefined reference to socket@12,在设置
-lws2_32并-lwsock32到 Code::Block 的链接器设置后,编译成功。
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
RDF_LOG(kDEBUG, "sockfd %d ", sockfd);
if (sockfd < 0){
RDF_LOG(kERROR, "ERROR: %s , errno %d\n", strerror(errno), errno);
}
Result --> sockfd -1 ERROR: No error , errno 0
结果 --> sockfd -1 错误:无错误,错误号 0
OK, I change RDF_LOG to fprintf instead.
好的,我将 RDF_LOG 改为 fprintf。
int tmp = 0;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
tmp = errno;
fprintf(stderr, "sockfd %d ", sockfd);
if (sockfd < 0){
fprintf(stderr, "socket: %s , errno %d\n", strerror(tmp), tmp);
}
The result returned is, still, --> sockfd -1 socket: No error , errno 0 Is it possible that mingw does not support errno??
返回的结果,还是,--> sockfd -1 socket: No error , errno 0 有没有可能mingw不支持errno??
回答by paxdiablo
The firstthing I would do is this:
我要做的第一件事是:
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
int tmp = errno;
RDF_LOG(kDEBUG, "sockfd %d ", sockfd);
if (sockfd < 0){
RDF_LOG(kERROR, "ERROR: %s , errno %d\n", strerror(tmp), tmp);
}
I have no idea what RDF_LOGmay be doing to the errnovariable and this will tell you whether it changes it or not.
我不知道变量RDF_LOG可能会做什么errno,这会告诉你它是否会改变它。
Another thing to look for is that you have successfully performed your WSAStartup. The following minimal program should hopefully show you how to do this, and provide a starting point for debugging:
要寻找的另一件事是您已成功执行您的WSAStartup. 以下最小程序应该会向您展示如何执行此操作,并提供调试的起点:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <winsock2.h>
int main (void) {
WSADATA wsaData;
int listenFd;
if (WSAStartup(MAKEWORD(1,1), &wsaData) == SOCKET_ERROR) {
printf ("Error initialising WSA.\n");
return -1;
}
listenFd = socket (AF_INET, SOCK_STREAM, 0);
if (listenFd < 0) {
printf ("Error %d opening socket.\n", errno);
return -1;
}
return 0;
}
回答by dgraves
Because you are working with Windows sockets, you will need to use the WSAGetLastError() function to check the error code. Windows sockets functions do not set errno, which is why you are seeing errno with a value of 0.
因为您使用的是 Windows 套接字,所以您需要使用 WSAGetLastError() 函数来检查错误代码。Windows 套接字函数不会设置 errno,这就是您看到 errno 值为 0 的原因。
This old MinGW wiki page has a list of differences between UNIX sockets and Windows sockets, mentioning the errno vs WSAGetLastError() difference in item 5: http://oldwiki.mingw.org/index.php/sockets
这个旧的 MinGW wiki 页面列出了 UNIX 套接字和 Windows 套接字之间的差异,在第 5 项中提到了 errno 与 WSAGetLastError() 的差异:http: //oldwiki.mingw.org/index.php/sockets
回答by Adam Rosenfield
The function/macro RDF_LOGis likely calling some other function in the C runtime library that is resetting errnoto 0. You need to capture the value of errnoimmediately after socketfails in order for it to be accurate.
函数/宏RDF_LOG很可能调用了 C 运行时库中重置errno为 0 的其他函数。您需要errno在socket失败后立即捕获 的值以使其准确。
回答by rkuczwara
Didn't see this mentioned in another answer, but there's another problem with the code above. Winsock socket descriptors are of type SOCKET, which in my MinGW winsock2.h is defined as unsigned int.
在另一个答案中没有看到这一点,但上面的代码还有另一个问题。Winsock 套接字描述符属于 SOCKET 类型,在我的 MinGW winsock2.h 中定义为 unsigned int。
If you are assuming Winsock sockets are of type int like Unix file descriptors, checking for a negative error return status may lead to false error reporting, since Winsock makes no guarantee that a socket descriptor value will map to a positive signed integer value.
如果您假设 Winsock 套接字的类型与 Unix 文件描述符类似,则检查负错误返回状态可能会导致错误的错误报告,因为 Winsock 不保证套接字描述符值将映射到正有符号整数值。
Winsock functions that return a socket descriptor (socket(), accept(), etc.) instead return SOCKET_INVALID on an error, which is defined as (SOCKET) ~0. As mentioned above, you should then use WSAGetLastError() to get the system error number.
返回套接字描述符(socket()、accept() 等)的 Winsock 函数在出现错误时返回 SOCKET_INVALID,该错误定义为 (SOCKET) ~0。如上所述,您应该然后使用 WSAGetLastError() 来获取系统错误号。
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx

