:: socket返回0和:: connect将errno设置为EBADF

时间:2012-05-21 11:15:12

标签: c++ sockets

我正在使用BSD套接字,我想使用::connect连接到端口80上的example.com::socket的手册页告诉我它返回一个有效的文件描述符,或者-1出错。

auto fd = ::socket(AF_INET, SOCK_STREAM, 0);

struct ::sockaddr_in addr;
::bzero(&addr, sizeof(addr));
addr.sin_family = family_;

struct ::hostent* hostent = ::gethostbyname(host.c_str());
::bcopy(hostent->h_addr, &addr.sin_addr.s_addr, hostent->h_length);
addr.sin_port = port;

auto err = ::connect(fd,
                     reinterpret_cast<struct ::sockaddr*>(&addr),
                     sizeof(addr));

fd == 0,所以::socket成功了(否则它会返回-1)。但是,err == -1errno设置为EBADF,表示fd是错误的文件描述符。

这可能会发生什么?为什么::connect告诉我,我给它一个错误的文件描述符,而我显然没有?

2 个答案:

答案 0 :(得分:1)

您应该确认socket 实际返回0?除非您关闭了标准文件描述符,否则这将非常不寻常。请确保在套接字呼叫后立即检查它,以防其他呼叫损坏。

答案 1 :(得分:0)

尝试将第三个参数显式传递给:: socket()调用,显式为IPPROTO_TCP。

auto fd = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

'0'值是IPPROTO_IP,这不是你需要的。

另一个猜测:尝试设置

addr.sin_addr = htons(port);

您可能正在连接到不可用的东西(端口不是80,正如您所期望的那样,但是0x5000 == 20480)。

第三次尝试。您正在使用BSD / MacOS,Linux或其他POSIX系统?还是WinSock?如果是windows,请检查WSAStartup调用。