socket() 返回 -1 但 errno 0

发布于 2024-12-13 04:33:05 字数 820 浏览 8 评论 0原文

我尝试在 mingw 上创建 UDP 套接字,但 socket() 返回 -1,errno = 0。奇怪的。 我已经包含了winsock2.h。 最初我在设置后遇到编译错误未定义的对socket@12的引用-lws2_32-lwsock32添加到Code::Block的Linker Settings中,编译成功。

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);
}

结果--> 套接字FD-1 错误:没有错误,errno 0


好的,我将 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);
}

返回的结果仍然是 --> sockfd -1 套接字:无错误,errno 0 难道mingw不支持errno吗?

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_32 and -lwsock32 to Linker Settings of Code::Block, compilation success.

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


OK, I change RDF_LOG to fprintf instead.

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??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

从﹋此江山别 2024-12-20 04:33:05

我要做的第一件事是:

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);
}

我不知道RDF_LOG可能会对errno变量做什么,这会告诉你它是否改变或不改变。

另一件需要注意的事情是您是否已成功执行 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;
}

The first thing 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_LOG may be doing to the errno variable and this will tell you whether it changes it or not.

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:

#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;
}
A君 2024-12-20 04:33:05

由于您使用的是 Windows 套接字,因此需要使用 WSAGetLastError() 函数来检查错误代码。 Windows 套接字函数不会设置 errno,这就是为什么您看到 errno 值为 0。

这个旧的 MinGW wiki 页面列出了 UNIX 套接字和 Windows 套接字之间的差异,在第 5 项中提到了 errno 与 WSAGetLastError() 的差异:
http://oldwiki.mingw.org/index.php/sockets

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.

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

梦在深巷 2024-12-20 04:33:05

函数/宏 RDF_LOG 可能会调用 C 运行时库中的其他函数,将 errno 重置为 0。您需要捕获 errno 的值code> 在 socket 失败后立即执行,以确保其准确。

The function/macro RDF_LOG is likely calling some other function in the C runtime library that is resetting errno to 0. You need to capture the value of errno immediately after socket fails in order for it to be accurate.

莫相离 2024-12-20 04:33:05

没有在另一个答案中看到这一点,但上面的代码还有另一个问题。 Winsock套接字描述符的类型为SOCKET,在我的MinGW的winsock2.h中定义为unsigned int。

如果您假设 Winsock 套接字是 int 类型(如 Unix 文件描述符),则检查负错误返回状态可能会导致错误报告,因为 Winsock 不保证套接字描述符值将映射到正符号整数值。

返回套接字描述符(socket()、accept() 等)的 Winsock 函数在出现错误时返回 SOCKET_INVALID,其定义为 (SOCKET) ~0。如上所述,您应该使用 WSAGetLastError() 来获取系统错误号。

https://msdn.microsoft .com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx

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.

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 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.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms740516%28v=vs.85%29.aspx

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文