views:

357

answers:

5

FINAL EDIT:

the code has been fixed to reflect changes. Thanks to all of you!!

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;
memcpy(&server_address.sin_addr, hserver->h_addr, hserver->h_length); // fixed part
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.

A: 

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.

Aaron Digulla
As I understand it, he has two clients and one of them can already connect succesfully.
ereOn
A: 

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).

ereOn
+2  A: 

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);
caf
I also removed the non-block, and it no longer hangs but gives 111: connection refused. This is strange because I'm running the other client on the same machine (as broken client) and server accepts connection just fine.
Fantastic Fourier
Well "connection refused" is pretty clear-cut. Perhaps your `SERVER_PORT` is wrong too.
caf
yea i can't believe I didn't catch that. 12345 and 12346 looked darned similar thanks to my non-existent eyesight.
Fantastic Fourier
A: 

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;
haavee
This is good advice, but I don't think it's the problem, because the `bind()` would fail (and the OP has error checking on that call).
caf
Would be interesting to get the value of SO_REUSEADDR. If it is set to true("1") then the bind() would not fail.
haavee
A: 

HEY FANTASTIC FOURIER; WHAT WAS YOU SOLUTION TO THIS ISSUE? I AM HAVING THE SAME PROBLEM.

THANK YOU