Reputation: 1099
I am establishing a server-client connection using TCP sockets. Whenever I close the client socket my server is also closed. But I want only my client to be closed and my server must wait for next accept()
.
Server side:
{
bind(lfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr));
listen(lfd, 10);
while(1)
{
cfd = accept(lfd, (struct sockaddr*)NULL, NULL);
//server must wait here after client closes the connection application code
close(lfd);
}
}
client side:
inet_pton(AF_INET, argv[1], &serv_addr.sin_addr);
connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
// ... application code
if(c == 1)
close(fd);
Upvotes: 3
Views: 49369
Reputation: 2186
The TCP listening socket described by the descriptor lfd
is used for waiting for TCP incoming connections at a specific port. After the call of accept
a new socket descriptor is created, the cfd
in your example.
All the data exchange between server and client is performed using the cfd
. If the client first close the socket, a possible send
or recv
at the server side, will return -1 with the appropriate errno
value.
If you want the server to close the connection, you should use shutdown(cfd, SHUT_RDWR)
and close(cfd)
after, NOT close(lfd)
. This lets the lfd
socket open, allowing the server to wait at the accept
for the next incoming connection. The lfd
should close at the termination of the server.
The shutdown()
provides more flexibility, to send or receive remaining data prior the permanent termination of the communication.
Upvotes: 6
Reputation: 25129
When you accept
server side, you generate a new socket for that client only.
When you have finished dealing with the client you must close()
that socket, (that's close(cfd)
in your terminology). You may also shutdown()
the socket - that will influence how the socket is closed at a TCP level. But whether you do or do not do a shutdown()
, you must close()
it, else you will leak FDs.
You must not close()
your listen fd (lfd
in your program) until you intend not to accept any more connections.
TLDR: change close(lfd)
to close(cfd)
Upvotes: 15
Reputation: 106
accept call would return new socket descriptor (cfd in your code) that is connected to the client side, so when client closes its end of connection cfd will be closed and not lfd. You can use lfd (listening socket) for accepting connection as long as server needs. Also consider invoking shutdown before close(fd) in client code.
Upvotes: 0