::socket returns 0 and ::connect sets errno to EBADF

I'm using BSD sockets and I want to use ::connect to connect to example.com on port 80. The man page of ::socket tells me that it returns either a valid file descriptor, or -1 on error.

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, so ::socket succeeded (otherwise it would've returned -1). However, err == -1 and errno is set to EBADF, indicating that fd is a bad file descriptor.

What could be going on here? Why does ::connect tell me that I gave it a bad file descriptor while I clearly did not?

2 Answers

You should confirm that socket is actually returning 0? Unless you've closed the standard file descriptors, that would be very unusual. Make sure you check it immediately after the socket call in case it's being corrupted by the other calls.

2

Try passing the third argument to the ::socket() call explicitly as IPPROTO_TCP.

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

The '0' value is IPPROTO_IP, which is not what you need.

Another guess: try setting

addr.sin_addr = htons(port); 

You might be connecting to something that is unavailable (the port is not 80, as you expect, but 0x5000 == 20480).

Third try. You are using BSD/MacOS, Linux or other POSIX-system ? Or the WinSock ? If windows, check for WSAStartup call.

3

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like