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

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

Post by Benoit GARBINA » Wed, 16 Mar 1994 04:08:32



The specification of the shutdown(s, 2) system call is to be "more
dramatic" than the close(s) system call, since any pending data is
lost. However, if you use shutdown(s, 2) instead of close(s) under
Solaris, you will have the * surprise to notice that the socket
isn't released at all. This mean that the following client/server
program will block at some stage. Furtermore, if you examine the
socket name space, by netstat -f unix, you will notice that more
than one socket with name "/tmp/foo" is registered by the system...

server.c
--------

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>

main()
{
  int sock, newsock, length;
  struct sockaddr_un name;
  char* buf[1024];

  for(;;)
  {
    sock = socket(AF_UNIX, SOCK_STREAM, 0);

    name.sun_family = AF_UNIX;
    strcpy(name.sun_path, "/tmp/foo");

    bind(sock, (struct sockaddr *)&name, sizeof name);
    listen(sock, 1);
    newsock = accept(sock, (struct sockaddr *) 0, (int *) 0);
    read(newsock, buf, 1024);
    printf("%s", buf);

    shutdown(sock, 2);
    shutdown(newsock, 2);
    unlink(name.sun_path);
  }

Quote:}

/* gcc server.c -o server -lsocket */

client.c
--------

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#define DATA "hello world\n"

main()
{
  int sock, length;
  struct sockaddr_un name;

  for(;;)
  {
    sleep(5);
    sock = socket(AF_UNIX, SOCK_STREAM, 0);

    name.sun_family = AF_UNIX;
    strcpy(name.sun_path, "/tmp/foo");

    connect(sock, (struct sockaddr *)&name, strlen(name.sun_path) +
                                          sizeof(name.sun_family));

    write(sock, DATA, sizeof(DATA));
    shutdown(sock, 2);
  }

Quote:}

/* gcc client.c -o client -lsocket */

Now if you simply replace all shutdown(s, 2) by close(s), it works
very well. Under SunOS-4, both calls lead to client/server program
that works. I haven't tested it with internet domain sockets yet.  

Any comment?

          \\|//
          |^ ^|          
          (O O)        
----oo0o---(_)---o0oo-------------------------------------------------------

Benoit Garbinato

Departement d'Informatique               (DI)   phone:  + 41 21 693 52 74
Ecole Polytechnique Federale de Lausanne (EPFL) fax:    + 41 21 693 39 09
CH-1015 LAUSANNE
(Switzerland)

 
 
 

1. UNIX domain sockets not closing cleanly

While communicating through unix domain sockets - I specify the socket
endpoint as a file in the tmp directory.
However, even when both the client and the server close the sockets and
exit - the file remains in the directory.

Do I need to remove the file explicitly using another system call or is
there any other socket call that I need to make
I am using solaris/x86 and linux - this happens on both

2. total freeze in logout

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

4. extendvg error

5. Closing sockets and closing connections

6. Any X-Clients available , which can run from windows can contact the linux boxes?

7. socket close doesn't really close

8. KNode Problem -- repeating prompts

9. close() versus shutdown() on sockets

10. When call shutdown(), how is socket fd closed?

11. Must I close() a shutdown() socket?

12. close or shutdown the tcp socket when it is in SYN_SEND

13. UNIX domain sockets vs TCP sockets