Tanaka Akira
unread,Feb 24, 2013, 2:34:19 AM2/24/13Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to min...@googlegroups.com
Hi.
I'm trying to use Unix domain socket on Minix but
my test program don't behave as I expected.
I have two questions:
1. Why accept() blocks until client closes socket?
2. Why read() on server blocks even after client exit?
My test program is follows.
$ uname -srvm
Minix 3.2.1 i686
$ cat server.c
/* usage: ./server [socket-filename] */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(int argc, char *argv[])
{
char *socket_filename = NULL;
struct sockaddr_un serv_addr;
struct sockaddr_un acpt_addr;
socklen_t acpt_len;
int serv_socket, acpt_socket;
char buf[4096];
ssize_t ssize;
int ret;
if (1 < argc)
socket_filename = argv[1];
else
socket_filename = "socket-file";
serv_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (serv_socket == -1) { perror("socket"); exit(EXIT_FAILURE); }
memset(&serv_addr, '\0', sizeof(serv_addr));
serv_addr.sun_family = AF_UNIX;
strcpy(serv_addr.sun_path, socket_filename);
ret = bind(serv_socket, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
if (ret == -1) { perror("bind"); exit(EXIT_FAILURE); }
ret = listen(serv_socket, 128);
if (ret == -1) { perror("listen"); exit(EXIT_FAILURE); }
fprintf(stderr, "before accept\n");
acpt_len = sizeof(acpt_addr);
acpt_socket = accept(serv_socket, (struct sockaddr *)&acpt_addr, &acpt_len);
if (acpt_socket == -1) { perror("accept"); exit(EXIT_FAILURE); }
fprintf(stderr, "after accept\n");
fprintf(stderr, "before read\n");
ssize = read(acpt_socket, buf, sizeof(buf));
if (ssize == -1) { perror("read"); exit(EXIT_FAILURE); }
fprintf(stderr, "after read\n");
return EXIT_SUCCESS;
}
$ cat client.c
/* usage: ./client [socket-filename] */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
int main(int argc, char *argv[])
{
char *socket_filename = NULL;
struct sockaddr_un conn_addr;
int clnt_socket;
int ret;
if (1 < argc)
socket_filename = argv[1];
else
socket_filename = "socket-file";
clnt_socket = socket(AF_UNIX, SOCK_STREAM, 0);
if (clnt_socket == -1) { perror("socket"); exit(EXIT_FAILURE); }
memset(&conn_addr, '\0', sizeof(conn_addr));
conn_addr.sun_family = AF_UNIX;
strcpy(conn_addr.sun_path, socket_filename);
ret = connect(clnt_socket, (struct sockaddr *)&conn_addr, sizeof(conn_addr));
if (ret == -1) { perror("connect"); exit(EXIT_FAILURE); }
sleep(5);
close(clnt_socket);
return EXIT_SUCCESS;
}
$ gcc -Wall -g server.c -o server
$ gcc -Wall -g client.c -o client
I run ./server and then ./client without arguments in different terminals:
(./client doesn't produce output.)
$ ./server
before accept
(blocks 5 seconds here after ./client run. Why accept() returns immediately?)
after accept
before read
(blocks here even after ./client exit. Why read() deosn't return?)
I think accept() should return just after client calls connect() and
read() should return 0 (EOF) just after client closes socket.
--
Tanaka Akira