socket()返回-1但是errno 0

时间:2011-11-01 04:41:51

标签: c sockets mingw codeblocks winsock2

我尝试在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);
}

结果 - &gt; sockfd -1 错误:没有错误,错误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);
}

返回的结果仍然是 - &gt; sockfd -1 socket:没有错误,错误0 是不是mingw不支持errno ??

4 个答案:

答案 0 :(得分:7)

第一个我会做的是:

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

答案 1 :(得分:5)

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

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

答案 2 :(得分:3)

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

答案 3 :(得分:0)

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

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

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

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