5

我试图在 mingw 上创建一个 UDP 套接字,但socket()返回-1errno = 0。奇怪的。我已经包含了winsock2.h。最初我有编译错误undefined reference to socket@12,在设置 -lws2_32-lwsock32链接代码设置后::块,编译成功。

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

结果 --> sockfd -1 ERROR: No error , 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 socket: No error , errno 0 是不是mingw不支持errno?

4

4 回答 4

8

我要做的第一件事是:

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;
}
于 2011-11-01T04:47:21.617 回答
6

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

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

于 2011-11-05T14:22:23.833 回答
3

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

于 2011-11-01T04:46:55.260 回答
0

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

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

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

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

于 2015-07-22T15:14:22.357 回答