yeah I don't have any code for that. So I'm just trying to
make sure I get everything right on my end.
Main Topics
Browse All TopicsI have a server which allows a dedicated client to connect
and pass data back and forth. The server which I coded runs on Linux and the client an executable I didn't code, runs on windows. My problem is that when the server is stopped and restarted while the client is connected I sometimes have to wait about a minute before I can get them talking again by stopping both of them. I suspect that the socket is still alive and thinks a connection is still there until it times out or something. I close the server which is running as a thread by exiting a while loop when a ctrl-c key combination is pressed.
while(!quit), where quit is set to true when a ctrl-c
is pressed.
After I break the while loop condition, I've tried the following with no luck.
pthread_exit(0); the while no longer stops with this
or
exit(0); results in a segfault
or
close(socketFileDescriptor
If I keep the server running and stop and start the client
it will reconnect but will no longer exchange data.
At this point I'm not sure if it's my code or the software I'm working with.
I have not set any socket options or have any code that removes sockets. I read that exit(0) should close all open file descriptors. The only thing I've used is
fcntl() to set the non_blocking option.
So I guess what my question comes down to is what is the proper way to gracefully shutdown a server running as a thread. Or have I tried the right things and the problem is not with my code?
Here is how I create the socket:
struct sockaddr_in server;
struct sockaddr_in client;
unsigned int serverDataLength, clientDataLength;
int serverSock_fd, client_fd;
serverSock_fd = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(5000);
serverDataLength = sizeof(server);
bind(serverSock_fd,(struct
,serverDataLength);
listen(serverSock_fd,1);
clientDataLength = sizeof(client);
client_fd = accept(serverSock_fd,(stru
int flag = fcntl(client_fd,F_GETFL,0)
fcntl(client_fd,F_SETFL, O_NONBLOCK|flag);
This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.
If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.
Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.
Access the answers to your technology questions today.
30-day free trial. Register in 60 seconds.
Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Try it out and discover for yourself.
30-day free trial. Register in 60 seconds.
Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.
using:
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,(const void* &on, sizeof(on));
solved half of my problem.
With the client running continuously trying to connect with the server. I can start and stop the server at will and the client connects and I don't have to wait.
My only problem now is if the Server is continuously running and after the client connects I stop the client, the server crashes with the message "broken pipe"
so I can't stop and start the client with the Server Continuosly.
I do also have
closesocket(client_fd);
I don't have my accept call in the while loop.
That is an obvious mistake on my part. I think I originally
put it in there and it wasn't working properly so I moved it out. After putting it back in the while loop it does
connect and disconnect with out crashing the server, but It
hangs before the accept call the second time through the
loop. So The processing stops.
createSocket(){
struct sockaddr_in server;
struct sockaddr_in client;
unsigned int serverDataLength, clientDataLength;
int serverSock_fd, client_fd;
serverSock_fd = socket(AF_INET, SOCK_STREAM, 0);
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(5000);
serverDataLength = sizeof(server);
bind(serverSock_fd,(struct
,serverDataLength);
listen(serverSock_fd,1);
clientDataLength = sizeof(client);
}
startServer(){
createSocket();
while(!quit){
client_fd = accept(serverSock_fd,(stru
int flag = fcntl(client_fd,F_GETFL,0)
fcntl(client_fd,F_SETFL, O_NONBLOCK|flag);
read(client_fd,&buf,sizeof
processMsg(buf);
}
}
Does your client follow request-response pattern,
creating a new connection for every data transfer?
Also, you set the socket to be non-blocking,
then, you need to handle all different cases for the read()
call, such as read() returns because it would block
(no data available), read() returns some data < sizeof(buf)
etc.
You need to somehow know how much data the client sends
and make another "while" loop around read() until the server reads that much data.
After you are done with the request, you need to close
client_fd at the end of the loop, before going back to
accept().
The connection is meant to stay active once made
until the session is over so a new connection is not
made for every data transfer.
For my program there is only one client that is
allowed to connect at any given time. Once the connection
is made the client starts sending messages of all types
and sizes each at different time intervals most at 4 per second, until the session is over.
The buffer is big enough to hold all messages that are
sent from the client for each read.
I've specified the socket to have allow one connection
at a time with listen(serverSock_fd,1); since there is only one possible client.
so once the client connects and I get my client
socket file descriptor I try to read that file
descriptor. It gets set from the return value
of accept.
what happens to the accept function call while
the client is connected the second time through the loop. Does it still get called
and reset the file Descriptor so my read call no
longer reads a valid file descriptor?
OK, then you need to move accept() before the "while".
accept() takes the first availble incoming TCP
connection and creates a new socket for it.
However, you still have a problem with not knowing
how much data the client sends. read() may return
-1 with errno==EWOULDBLOCK if there is no data available,
or it may return any number of bytes that is ready,
but not necessary all bytes that client sent.
It's true I don't know exactly how much data will
be there for any given read() and sometimes it was returning -1 , but it wasn't blocking.
I was printing out the bytes read and saw the -1
so I added this:
int bytes_read = read(...);
if (bytes_read > 0){
processMsg(buf);
}
I suppose the NON_BLOCKING flag allowed me to continue
reading.
So if I have the accept() outside of the while loop.
and the client disconnects and then trys to reconnect
,since I don't have an accept() call in the while loop
it should fail right?
If closing the file descriptor is what's necessary when the client disconnects, how can the server know when the
connection is closed.
I was thinking if I put the accept() call in the while loop
, but only called it when I know there isn't a connection
active.
something like the following.
bool connected = false;
if(!connected){
accept();
connected = true;
}
If I know when a connection is closed I could set connection = false;
Do you think this would work?
is there a way to know when the connection is closed?
A connection is closed when read() returns 0.
Also, you may want to check the errno when read()
returns -1.
If errno==EWOULDBLOCK, then it's fine since
read() returned because no data availble.
If errno != EWOULDBLOCK, then an error occured.
It may work, though in general it is not a good design.
Your server continuosly loops around wasting CPU time.
A better solution might be to use select().
Business Accounts
Answer for Membership
by: jhancePosted on 2002-04-30 at 15:38:14ID: 6982193
Can I assume that you do not have access to the client code?