2

我正在使用 BSD 套接字,我想用来::connect连接到example.com端口 80。手册页::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告诉我我给了它一个错误的文件描述符,而我显然没有?

4

2 回答 2

2

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

于 2012-05-21T11:27:05.167 回答
0

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

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 调用。

于 2012-05-21T11:22:00.047 回答