Nerdy
Nerdy

Reputation: 1099

closing client socket and keeping server socket active

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

Answers (3)

Manos
Manos

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 accepta 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

abligh
abligh

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

lonewasp
lonewasp

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

Related Questions