public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* socket write(2) after remote shutdown(2) problem ?
@ 2002-04-05  9:50 Stelian Pop
  2002-04-05 10:04 ` David S. Miller
  0 siblings, 1 reply; 11+ messages in thread
From: Stelian Pop @ 2002-04-05  9:50 UTC (permalink / raw)
  To: Linux Kernel Mailing List

[-- Attachment #1: Type: text/plain, Size: 639 bytes --]

Hi,

Is the following behaviour correct on a tcp connection: 
	* the server issues a shutdown(sock, RW)
	* the client side socket passes in CLOSE-WAIT state
	* the client issues a write on the socket which succeds.

I expected the last write to fail, since the other side is not
capable any more to receive data. Can someone confirm to me one
of the following:
	1. behaviour is correct and why.
	2. shutdown is buggy.
	3. write is buggy.

Thanks.

Attached are sample codes for the "server" and the "client". Test
was done on latest 2.4 and 2.5 kernels.

Stelian.
-- 
Stelian Pop <stelian.pop@fr.alcove.com>
Alcove - http://www.alcove.com

[-- Attachment #2: client.c --]
[-- Type: text/plain, Size: 1931 bytes --]

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

char buf[1024];

int main()
{
  int fd;
  char * ptr;
  struct sockaddr_in addr;
  int ready = 0;
  fd_set rfds, efds;
  int nread;

  /* establish connection */

  fd = socket (PF_INET, SOCK_STREAM, 0);
  if ( -1 == fd) {
    perror ("socket");
    exit (1);
  }

  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl (INADDR_ANY);
  addr.sin_port = 0;
  if (bind (fd, (struct sockaddr*)&addr, sizeof (struct sockaddr_in)) != 0) {
    perror ("bind");
    exit (1);
  }

  ptr = (char*)&addr.sin_addr.s_addr;
  /*  ptr[0] = 162; ptr[1] = 0; ptr[2] = 120; ptr[3] = 98;*/
  ptr[0] = 127; ptr[1] = 0; ptr[2] = 0; ptr[3] = 1;
  addr.sin_port = htons(9999);
  if (connect (fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
    perror ("connect");
    exit (1);
  }
  
  FD_ZERO (&rfds);
  FD_SET (fd, &rfds);
  select (fd+1, &rfds, 0, 0, 0);

  /* read everything from socket and print it to stdout */

  while (!ready) {
    struct timeval tv;

    FD_ZERO (&rfds);
    FD_SET (fd, &rfds);
    FD_ZERO (&efds);
    FD_SET (fd, &efds);
    memset (&tv, 0, sizeof(tv));

    switch (select (fd+1, &rfds, 0, &efds, &tv)) {
    case -1:
      perror("select");
      exit (1);
    case 0:
      ready = 1;
      break;
    case 1:
      if (FD_ISSET (fd, &efds)) {
	fprintf (stderr, "select found exception");
      }
      nread = read (fd, &buf, 1024);
      if (nread == 0)
	ready = 1;
      else
	write (1, &buf, nread);
      break;
    }
  }

  /* here lsof will show CLOSE_WAIT */
  raise (SIGSTOP);

{
int ret;

  if ((ret = write (fd, "QUIT\n", 5)) == -1) {
    perror ("write");
    exit (1);
  }
  printf("write ok, ret=%d\n", ret);
}

  /* here the socket is orphaned, after write succeeded */
  raise (SIGSTOP);

  return 0;
}

[-- Attachment #3: server.c --]
[-- Type: text/plain, Size: 1071 bytes --]

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/select.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <signal.h>

char buf[1024];

int main()
{
  int fd, conn;
  struct sockaddr_in addr;
  socklen_t size;

  /* get socket to client, listening on 9999 */

  fd = socket (PF_INET, SOCK_STREAM, 0);
  if ( -1 == fd) {
    perror ("socket");
    exit (1);
  }

  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = htonl (INADDR_ANY);
  addr.sin_port = htons(9999);
  if (bind (fd, (struct sockaddr*)&addr, sizeof (struct sockaddr_in)) != 0) {
    perror ("bind");
    exit (1);
  }

  if (-1 == listen (fd, 1)) {
    perror ("listen");
    exit (1);
  }

  if (-1 == (conn = accept(fd, (struct sockaddr*)&addr, &size))) {
    perror ("accept");
    exit (1);
  }

  /* send some info */

  if (write (conn, "Hello client !\n", 15) == -1) {
    perror ("write");
    exit (1);
  }

  /* finish */

  if (-1 == shutdown (conn, SHUT_RDWR)) {
    perror ("shutdown");
    exit (1);
  }

  return 0;
}

^ permalink raw reply	[flat|nested] 11+ messages in thread
[parent not found: <20020405104733.GD16595@come.alcove-fr.suse.lists.linux.kernel>]

end of thread, other threads:[~2002-04-05 12:59 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-04-05  9:50 socket write(2) after remote shutdown(2) problem ? Stelian Pop
2002-04-05 10:04 ` David S. Miller
2002-04-05 10:47   ` Stelian Pop
2002-04-05 10:44     ` David S. Miller
2002-04-05 10:55       ` Stelian Pop
2002-04-05 11:02         ` David S. Miller
2002-04-05 12:00           ` Stelian Pop
2002-04-05 12:04             ` David S. Miller
2002-04-05 12:23               ` Stelian Pop
2002-04-05 12:59               ` Stelian Pop
     [not found] <20020405104733.GD16595@come.alcove-fr.suse.lists.linux.kernel>
     [not found] ` <20020405.024435.88131177.davem@redhat.com.suse.lists.linux.kernel>
     [not found]   ` <20020405105509.GE16595@come.alcove-fr.suse.lists.linux.kernel>
     [not found]     ` <20020405.030251.28451401.davem@redhat.com.suse.lists.linux.kernel>
2002-04-05 11:47       ` Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox