简体   繁体   中英

C socket programming: connect() hangs

Hey all, I'm about to rip my hair out. I have this client that tries to connect to a server, everything seems to be fine, using gethostbyname() , socket() , bind() , but when trying to connect() it just hangs there and the server doesn't see anything from the client. I know that the server works because another client (also in C) can connect just fine. What causes the server to not see this incoming connection? I'm at the end of my wits here. The two different clients are pretty similar too so I'm even more lost.

    if (argc == 2)  {
    host = argv[1];         // server address
}
else    {
    printf("plz read the manual\n");
    exit(1);
}

hserver = gethostbyname(host);
if (hserver)    {
    printf("host found: %p\n", hserver);
    printf("host found: %s\n", hserver->h_name );
}
else    {
    printf("host not found\n");
    exit(1);
}

bzero((char * ) &server_address, sizeof(server_address)); // copy zeroes into string
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(hserver->h_addr);
server_address.sin_port = htons(SERVER_PORT);

bzero((char * ) &client_address, sizeof(client_address)); // copy zeroes into string
client_address.sin_family = AF_INET;
client_address.sin_addr.s_addr = htonl(INADDR_ANY);
client_address.sin_port = htons(SERVER_PORT);

sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
    exit(1);
else    {
    printf("socket is opened: %i \n", sockfd);
    info.sock_fd = sockfd;
    rv = fcntl(sockfd, F_SETFL, O_NONBLOCK); // socket set to NONBLOCK
    if(rv < 0)
        printf("nonblock failed: %i %s\n", errno, strerror(errno));
    else
        printf("socket is set nonblock\n");
}

timeout.tv_sec = 0;     // seconds
timeout.tv_usec = 500000; // micro seconds ( 0.5 seconds)
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval));

rv = bind(sockfd, (struct sockaddr *) &client_address, sizeof(client_address));
if (rv < 0)     {
    printf("MAIN: ERROR bind() %i: %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("socket is bound\n");

rv = connect(sockfd, (struct sockaddr *) &server_address, sizeof(server_address));
printf("rv = %i\n", rv);
if (rv < 0)     {
    printf("MAIN: ERROR connect() %i:  %s\n", errno, strerror(errno));
    exit(1);
}
else
    printf("connected\n");

Any thoughts or insights are deeply greatly humongously appreciated.

-Fourier

EDIT: If the socket is NOT set on non-block, then it hangs. If the socket is set on non-block, then I get ERROR connect() 115: Operation now in progress

[EINPROGRESS] O_NONBLOCK is set for the file descriptor for the socket and the connection cannot be immediately established; the connection shall be established asynchronously.

I would also like to mention that the server and the client are running on computers next to each other, connected by like one router.

The gethostbyname() function produces addresses in network byte order, so you do not need to pass them through htonl() . Also, the hostent->h_addr entry is a pointer to the address. Replace this line:

server_address.sin_addr.s_addr = htonl(hserver->h_addr);

with:

memcpy(&server_address.sin_addr, hserver->h_addr, hserver->h_length);

I see you set your socket in O_NONBLOCK mode.

Thus connect must return -1 and set errno to EAGAIN according to the man page of connect .

You can then know when the connection succeeded using select() on the socket.

This is a very common pattern to control the connection timeout (because select() must be feed with a timeout).

Check whether you can connect with the program telnet (it accepts a server name and port number). If that works, the bug must be in your code. If telnet also hangs, then check your firewall settings.

If you want to connect twice from the same machine I can see the reason for your problem.

You are binding the clientsocket. Your code binds the client socket very specifically to a fixed port (the server port). This leaves the O/S NOT free in choosing an available port for making the connection FROM. If one process has the port allocated (it has succesfully bound() and connected() to the server) then the other process cannot use that same port.

If there is no compelling reason for sending traffic FROM a specific port, let the O/S find an available port by changing this line

client_address.sin_port = htons(SERVER_PORT);

to

client_address.sin_port = 0;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM