=================================================================== RCS file: /home/cvs/OpenXM/src/ox_toolkit/mysocket.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -p -r1.4 -r1.5 --- OpenXM/src/ox_toolkit/mysocket.c 2000/10/10 05:23:20 1.4 +++ OpenXM/src/ox_toolkit/mysocket.c 2000/11/30 16:07:35 1.5 @@ -1,6 +1,6 @@ /* -*- mode: C; coding: euc-japan -*- */ -/* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.3 2000/01/13 07:57:09 ohara Exp $ */ -/* +/* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.4 2000/10/10 05:23:20 ohara Exp $ */ +/* Q: How to get a local port number? A: You do setsockopt() to set options and do socket(), bind(). An OS set a local port for you. @@ -8,7 +8,7 @@ In order to get the local port, you need to do getsock (See [1] pp. 91, pp. 187 for detail) Reference -[1] W. Richard Stevens, "UNIX Network Programming", 2nd ed. Vol. 1 +[1] W. Richard Stevens, "UNIX Network Programming", 2nd ed. Vol. 1 (Japanese version) */ #include @@ -28,66 +28,83 @@ Reference #include "mysocket.h" -static int getsocket(struct sockaddr_in *mp, char *host, short port) +typedef struct ox_sockopt { + int level; + int option_name; + void* option_value; + socklen_t option_len; +} ox_sockopt; + +static int getsocket(struct sockaddr_in *mp, char *host, int port) { struct hostent *ent = gethostbyname(host); - + memset(mp, '\0', sizeof(struct sockaddr_in)); mp->sin_family = AF_INET; - mp->sin_port = htons(port); + mp->sin_port = htons((short)port); memcpy((char *)&mp->sin_addr, ent->h_addr, ent->h_length); return socket(AF_INET, SOCK_STREAM, 0); } -int mysocketAccept(int s_waiting) +static int ox_connect(char *hostname, int port, ox_sockopt *opt) { - return accept(s_waiting, NULL, NULL); + struct sockaddr_in serv; + int s = getsocket(&serv, hostname, port); + if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) { + fprintf(stderr, "ox_connect: failed. socket = %d, errno = %d\n", s, errno); + return -1; + } + return s; } -int mysocketListen(char *hostname, short *portp) +static int ox_listen(char *hostname, int *port, int backlog, ox_sockopt *opt) { - int option; - int tmp; struct sockaddr_in me; - - int s_waiting = getsocket(&me, hostname, *portp); + int s_waiting = getsocket(&me, hostname, *port); - option = 1; - setsockopt(s_waiting, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); - - if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0) { - fprintf(stderr, "bind: failed.\n"); - exit(1); + setsockopt(s_waiting, opt->level, opt->option_name, + opt->option_value, opt->option_len); + if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0 + || listen(s_waiting, backlog) < 0) { + fprintf(stderr, "ox_listen: failed.\n"); + return -1; } + return s_waiting; +} - tmp = sizeof(me); - if (getsockname(s_waiting, (struct sockaddr *)&me, &tmp) < 0) { - fprintf(stderr, "getsockname is failed.\n"); - exit(1); +static int ox_getport(int s_waiting) +{ + struct sockaddr_in me; + int len = sizeof(me); + if (getsockname(s_waiting, (struct sockaddr *)&me, &len) < 0) { + fprintf(stderr, "ox_getport: failed.\n"); + return -1; } + return ntohs(me.sin_port); +} - *portp = ntohs(me.sin_port); - - if (listen(s_waiting, 1) < 0) { - fprintf(stderr, "listen: failed.\n"); - exit(1); - } - - return s_waiting; +int mysocketAccept(int s_waiting) +{ + /* return ox_accept(s_waiting); */ + return accept(s_waiting, NULL, NULL); } -int mysocketOpen(char* hostname, short port) +int mysocketListen(char *hostname, int *port) { - struct sockaddr_in serv; - int s = getsocket(&serv, hostname, port); + int option = 1; + ox_sockopt opt = {SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)}; + int s_waiting = ox_listen(hostname, port, 1, &opt); - fprintf(stderr, "get socket address for port number %d.\n", port); - if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) { - fprintf(stderr, "connect: fail! socket = %d, errno = %d\n", s, errno); - exit(-1); + if (*port == 0) { + *port = ox_getport(s_waiting); } - return s; + return s_waiting; +} + +int mysocketOpen(char* hostname, int port) +{ + return ox_connect(hostname, port, NULL); } #if 0