I am using BSD TCP sockets under Debian Linux 2.6 and no matter what I do, the socket blocks on recv.
I have set O_NONBLOCK and O_NDELAY using fcntl to no effect.
Any ideas ?
I am using BSD TCP sockets under Debian Linux 2.6 and no matter what I do, the socket blocks on recv.
I have set O_NONBLOCK and O_NDELAY using fcntl to no effect.
Any ideas ?
Have you tried select() with timeout set to non-NULL?
Without your code, this amounts to a wild guess.....
The following is my code for both server and client sockets: -
bzero(&sa,sizeof(struct sockaddr_in)); /* clear our address */
if (master) {
if (gethostname(myname,MAXHOSTNAME) < 0) std::cerr << "Error hostname: " << myname; /* who are we? */
hp= gethostbyname(myname); /* get our address info */
if (hp != NULL) {
sa.sin_family= hp->h_addrtype; /* this is our host address */
sa.sin_port= htons(port); /* this is our port number */
}
if ((s= socket(AF_INET,SOCK_STREAM,0)) >= 0) { /* create socket */
int on = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (bind(s, reinterpret_cast<struct sockaddr*>(&sa), sizeof sa) >= 0) { /* bind address to socket */
listen(s, 3); /* max # of queued connects */
established = true;
master_socket_ref = s;
int flags = fcntl(master_socket_ref, F_GETFL, 0);
fcntl(master_socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC);
}
else close(s);
}
}
else {
if ((hp= gethostbyname(node_name(node_ref).c_str())) != NULL) {
bzero(&sa,sizeof(sa));
bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); /* set address */
sa.sin_family= hp->h_addrtype;
sa.sin_port= htons(port);
if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) >= 0) { /* get socket */
int on = 1;
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
if (connect(s, reinterpret_cast<struct sockaddr*>(&sa), sizeof sa) >= 0) { /* Connect */
established = true;
socket_ref = s;
int flags = fcntl(socket_ref, F_GETFL, 0);
fcntl(socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC);
}
else close(s);
}
}
}
If I have set up a server listening socket using the above code, I accept a client as follows :-
getsockname(master_socket_ref, reinterpret_cast<struct sockaddr*>(&isa), reinterpret_cast<socklen_t*>(&i)); /* for accept() */
int on = 1;
socket_ref = accept(master_socket_ref, reinterpret_cast<struct sockaddr*>(&isa), reinterpret_cast<socklen_t*>(&i));
setsockopt(socket_ref, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
int flags = fcntl(socket_ref, F_GETFL, 0);
fcntl(socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC);
Many thanks Jim, the Select API seems to fix the blocking issue (I used a 100 msec timeout on select()). Although I haven't test the received data path properly yet, but the blocking is not an issue anymore.
For others who are interested, the following may be interesting to you :-