Trouble closing sockets....

Trouble closing sockets....

Post by Brook » Sat, 04 Sep 1999 04:00:00



You didn't include the code for the client, so here is my guess...

to quit the connection, the client must send a '|' followed by a 'q'
followed by some other character before you close and clear the socket.
I'll guess that your client isn't sending the third character and the server
blocks on the read (the one right after the 'q' is identified).

If this isn't right, post the client code as well.

brooks


>Hello,

>I am just testing out unix sockets and I have created a server program so
>that a number of clients can connect and chat back and forth.  I am
creating
>it in Linux kernel 2.2.5 and everything is working just great.  The clients
>can talk back and forth to each other, but when 1 client disconnects, thats
>it.  No more talking.  Nothing seems to get through to the server.  I have
>no idea what is going on.  Can someone look at the code below and tell me
>what blaring mistakes I have made on this subject.  I know I am doing some
>things weird but please remeber that this is just for test purposes and the
>real problem I am having is with the clients freezing after one quits...

>Thank you for advance.  And Now for the code ;)

>int main(int argc, char **argv)
>{
>  int i, maxi, maxfd, listenfd, connfd, sockfd;
>  int nready, clientlen, client[FD_SETSIZE], count = 0;
>  ssize_t n;
>  fd_set rset, allset;
>  char line[MAXLINE], number[8], converted[15];
>  struct sockaddr_in cliaddr, servaddr;

>  listenfd = socket(AF_INET, SOCK_STREAM, 0);

>  bzero(&servaddr, sizeof(servaddr));
>  servaddr.sin_family = AF_INET;
>  servaddr.sin_addr.s_addr = htonl(ADDRESS);
>  servaddr.sin_port = htons(PORT);

>  bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

>  listen(listenfd, LISTENQ);

>  maxfd = listenfd;                         // intialize
>  maxi  = -1;                               // index int client[] array
>  for(i=0;i<FD_SETSIZE;i++) client[i] = -1; // -1 indicates avail entry
>  FD_ZERO(&allset);
>  FD_SET(listenfd, &allset);

>  // the infiniate loop
>  for(;;){
>    rset = allset;                          // struct assignment
>    nready = select(maxfd + 1, &rset, NULL, NULL, NULL);

>    if (FD_ISSET(listenfd, &rset)){         // new client connection
>      clientlen = sizeof(cliaddr);
>      connfd = accept(listenfd, (SA *) &cliaddr, &clientlen);

>        for(i=0;i<FD_SETSIZE;i++){
>        if (client[i] < 0){
>          client[i] = connfd;               // save descriptor
>          break;
>        }
>      }

>      if (i == FD_SETSIZE){
>        printf("Too many clients!\n");
>        exit(0);
>      }

>      FD_SET(connfd, &allset);              // add new desc to set
>      if (connfd > maxfd) maxfd = connfd;
>      if (i > maxi) maxi = i;               // max index in client array
>      if (--nready <= 0) continue;          // no more readable desc
>    }

>    for(i=0;i<=maxi;i++){                   // check all clients for data
>      if ((sockfd = client[i]) < 0) continue;

>      if (FD_ISSET(sockfd, &rset)){
>        handle(sockfd, client, i, &allset, maxi);

>        if (--nready <= 0) break;
>      }
>    }
>  }
>}

>// read the socket stuff and send out the packets to the appropriate
>// sockets
>//
>void handle(int sockfd, int *client, int clientnum, fd_set *set, int maxi)
>{
>  char c, i;
>  int status = 0, other;

>  read(sockfd, &c, 1);
>  printf("%c",c);

>  // the client has sent a pipe which means that there is a command that
>  // we must carry out
>  //
>  if (c == '|'){
>    read(sockfd, &c, 1);

>    // this is where we decide what is going on with the command
>    if (c == 'q'){
>      read(sockfd, &c, 1);

>      close(sockfd);
>      FD_CLR(sockfd, &set);
>      client[clientnum] = -1;
>      printf("Closing socket: %d, clientnum: %d\n",sockfd,clientnum);
>    }
>  }
>  else{
>    for(i=0;i<=maxi;i++){
>      other = client[i];

>      if ((other > 0) && (sockfd != other)){
>        if (write(other, &c, 1) != 1){
>          printf("Can't write to socket!\n");
>          close(other);
>          FD_CLR(other, &set);
>          client[i] = -1;
>          exit(0);
>        }
>      }
>    }
>  }
>}

 
 
 

Trouble closing sockets....

Post by David Carachel » Sun, 05 Sep 1999 04:00:00


Hello,

I am just testing out unix sockets and I have created a server program so
that a number of clients can connect and chat back and forth.  I am creating
it in Linux kernel 2.2.5 and everything is working just great.  The clients
can talk back and forth to each other, but when 1 client disconnects, thats
it.  No more talking.  Nothing seems to get through to the server.  I have
no idea what is going on.  Can someone look at the code below and tell me
what blaring mistakes I have made on this subject.  I know I am doing some
things weird but please remeber that this is just for test purposes and the
real problem I am having is with the clients freezing after one quits...

Thank you for advance.  And Now for the code ;)

int main(int argc, char **argv)
{
  int i, maxi, maxfd, listenfd, connfd, sockfd;
  int nready, clientlen, client[FD_SETSIZE], count = 0;
  ssize_t n;
  fd_set rset, allset;
  char line[MAXLINE], number[8], converted[15];
  struct sockaddr_in cliaddr, servaddr;

  listenfd = socket(AF_INET, SOCK_STREAM, 0);

  bzero(&servaddr, sizeof(servaddr));
  servaddr.sin_family = AF_INET;
  servaddr.sin_addr.s_addr = htonl(ADDRESS);
  servaddr.sin_port = htons(PORT);

  bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

  listen(listenfd, LISTENQ);

  maxfd = listenfd;                         // intialize
  maxi  = -1;                               // index int client[] array
  for(i=0;i<FD_SETSIZE;i++) client[i] = -1; // -1 indicates avail entry
  FD_ZERO(&allset);
  FD_SET(listenfd, &allset);

  // the infiniate loop
  for(;;){
    rset = allset;                          // struct assignment
    nready = select(maxfd + 1, &rset, NULL, NULL, NULL);

    if (FD_ISSET(listenfd, &rset)){         // new client connection
      clientlen = sizeof(cliaddr);
      connfd = accept(listenfd, (SA *) &cliaddr, &clientlen);

        for(i=0;i<FD_SETSIZE;i++){
        if (client[i] < 0){
          client[i] = connfd;               // save descriptor
          break;
        }
      }

      if (i == FD_SETSIZE){
        printf("Too many clients!\n");
        exit(0);
      }

      FD_SET(connfd, &allset);              // add new desc to set
      if (connfd > maxfd) maxfd = connfd;
      if (i > maxi) maxi = i;               // max index in client array
      if (--nready <= 0) continue;          // no more readable desc
    }

    for(i=0;i<=maxi;i++){                   // check all clients for data
      if ((sockfd = client[i]) < 0) continue;

      if (FD_ISSET(sockfd, &rset)){
        handle(sockfd, client, i, &allset, maxi);

        if (--nready <= 0) break;
      }
    }
  }

Quote:}

// read the socket stuff and send out the packets to the appropriate
// sockets
//
void handle(int sockfd, int *client, int clientnum, fd_set *set, int maxi)
{
  char c, i;
  int status = 0, other;

  read(sockfd, &c, 1);
  printf("%c",c);

  // the client has sent a pipe which means that there is a command that
  // we must carry out
  //
  if (c == '|'){
    read(sockfd, &c, 1);

    // this is where we decide what is going on with the command
    if (c == 'q'){
      read(sockfd, &c, 1);

      close(sockfd);
      FD_CLR(sockfd, &set);
      client[clientnum] = -1;
      printf("Closing socket: %d, clientnum: %d\n",sockfd,clientnum);
    }
  }
  else{
    for(i=0;i<=maxi;i++){
      other = client[i];

      if ((other > 0) && (sockfd != other)){
        if (write(other, &c, 1) != 1){
          printf("Can't write to socket!\n");
          close(other);
          FD_CLR(other, &set);
          client[i] = -1;
          exit(0);
        }
      }
    }
  }

Quote:}


 
 
 

1. close() trouble with sockets

I'm running a small server on Red Hat Linux 7.0 / Kernel 2.2.16-22smp (2x
i686).

It's using sockets in non blocking mode, with SO_KEEPALIVE set to 1, and
SO_LINGER set to l_onoff=1, l_linger=0.

What happens, is that the server blocks in a close(socket) call sometimes.
It calls close, and doesn't return from it, it's blocking in there for some
reason.

If one runs gdb, you find that it's in the system call for close(). And if
you detach the program and let it keep running, since you knocked it out of
that blocking close call, it proceeds normally and runs fine again for a
while.

There's no breakpoints set, the program seems to stop randomly on that close
call.

What am I doing wrong?

I used to run this little server on Solaris-86 (2.6), and it ran smoothly
with no problems.

Aleksi Asikainen

2. Allocation of colormap

3. shutdown(s, 2) vs close(s) for closing unix domain sockets

4. output from script

5. Sockets: close() does not close!?

6. 1-to-many port "scan"s?

7. Closing sockets and closing connections

8. Problems: D-Link "DFE-530TX+

9. socket close doesn't really close

10. Reclaiming used socket fd or how to close sockets properly

11. help: close(socket) leaves socket bound ?

12. Sockets: server close leaves socket bound?

13. Closing sockets