| version 1.3, 2000/01/13 07:57:09 |
version 1.7, 2003/01/11 11:42:31 |
|
|
| /* -*- mode: C; coding: euc-japan -*- */ |
/* -*- mode: C; coding: euc-japan -*- */ |
| /* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.2 2000/01/05 06:05:35 ohara Exp $ */ |
/* $OpenXM: OpenXM/src/ox_toolkit/mysocket.c,v 1.6 2000/12/01 16:31:11 ohara Exp $ */ |
| /* |
/* |
| Q: How to get a local port number? |
Q: How to get a local port number? |
| A: You do setsockopt() to set options and do socket(), bind(). |
A: You do setsockopt() to set options and do socket(), bind(). |
| An OS set a local port for you. |
An OS set a local port for you. |
| Line 8 In order to get the local port, you need to do getsock |
|
| Line 8 In order to get the local port, you need to do getsock |
|
| (See [1] pp. 91, pp. 187 for detail) |
(See [1] pp. 91, pp. 187 for detail) |
| |
|
| Reference |
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 <stdio.h> |
#include <stdio.h> |
|
|
| #include <unistd.h> |
#include <unistd.h> |
| #include <errno.h> |
#include <errno.h> |
| #include <netdb.h> |
#include <netdb.h> |
| |
#include <string.h> |
| #include <netinet/in.h> |
#include <netinet/in.h> |
| #include <sys/types.h> |
#include <sys/types.h> |
| #include <sys/socket.h> |
#include <sys/socket.h> |
|
|
| #endif |
#endif |
| |
|
| #include "mysocket.h" |
#include "mysocket.h" |
| |
#include "ox_toolkit.h" |
| |
|
| static int getsocket(struct sockaddr_in *mp, char *host, short port) |
typedef struct ox_sockopt { |
| |
int level; |
| |
int option_name; |
| |
void* option_value; |
| |
int option_len; |
| |
} ox_sockopt; |
| |
|
| |
static int getsocket(struct sockaddr_in *mp, char *host, int port) |
| { |
{ |
| struct hostent *ent = gethostbyname(host); |
struct hostent *ent = gethostbyname(host); |
| |
|
| memset(mp, '\0', sizeof(struct sockaddr_in)); |
memset(mp, '\0', sizeof(struct sockaddr_in)); |
| mp->sin_family = AF_INET; |
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); |
memcpy((char *)&mp->sin_addr, ent->h_addr, ent->h_length); |
| |
|
| return socket(AF_INET, SOCK_STREAM, 0); |
return socket(AF_INET, SOCK_STREAM, 0); |
| } |
} |
| |
|
| int mysocketAccept(int s_waiting) |
static int ox_connect(char *hostname, int port, ox_sockopt *opt) |
| { |
{ |
| int val = accept(s_waiting, NULL, NULL); |
struct sockaddr_in serv; |
| return val; |
int s = getsocket(&serv, hostname, port); |
| |
if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) { |
| |
fprintf(ox_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; |
struct sockaddr_in me; |
| |
int s_waiting = getsocket(&me, hostname, *port); |
| int s_waiting = getsocket(&me, hostname, *portp); |
|
| |
|
| option = 1; |
setsockopt(s_waiting, opt->level, opt->option_name, |
| setsockopt(s_waiting, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); |
opt->option_value, opt->option_len); |
| |
if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0 |
| if (bind(s_waiting, (struct sockaddr *)&me, sizeof(me)) < 0) { |
|| listen(s_waiting, backlog) < 0) { |
| fprintf(stderr, "bind: failed.\n"); |
fprintf(ox_stderr, "ox_listen: failed.\n"); |
| exit(1); |
return -1; |
| } |
} |
| |
return s_waiting; |
| |
} |
| |
|
| tmp = sizeof(me); |
static int ox_getport(int s_waiting) |
| if (getsockname(s_waiting, (struct sockaddr *)&me, &tmp) < 0) { |
{ |
| fprintf(stderr, "getsockname is failed.\n"); |
struct sockaddr_in me; |
| exit(1); |
int len = sizeof(me); |
| |
if (getsockname(s_waiting, (struct sockaddr *)&me, &len) < 0) { |
| |
fprintf(ox_stderr, "ox_getport: failed.\n"); |
| |
return -1; |
| } |
} |
| |
return ntohs(me.sin_port); |
| |
} |
| |
|
| *portp = ntohs(me.sin_port); |
int mysocketAccept(int s_waiting) |
| |
{ |
| if (listen(s_waiting, 1) < 0) { |
/* return ox_accept(s_waiting); */ |
| fprintf(stderr, "listen: failed.\n"); |
return accept(s_waiting, NULL, NULL); |
| exit(1); |
|
| } |
|
| |
|
| return s_waiting; |
|
| } |
} |
| |
|
| int mysocketOpen(char* hostname, short port) |
int mysocketListen(char *hostname, int *port) |
| { |
{ |
| struct sockaddr_in serv; |
int option = 1; |
| int s = getsocket(&serv, hostname, port); |
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 (*port == 0) { |
| if (connect(s, (struct sockaddr *)&serv, sizeof(serv)) != 0) { |
*port = ox_getport(s_waiting); |
| fprintf(stderr, "connect: fail! socket = %d, errno = %d\n", s, errno); |
|
| exit(-1); |
|
| } |
} |
| return s; |
return s_waiting; |
| } |
} |
| |
|
| |
int mysocketOpen(char* hostname, int port) |
| |
{ |
| |
return ox_connect(hostname, port, NULL); |
| |
} |
| |
|
| #if 0 |
#if 0 |
| int mypipe(char *program, int fd1, int fd2) |
int mypipe(char *program, int fd1, int fd2) |
| { |
{ |
| int sockfd[2]; |
int sockfd[2]; |
| if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) { |
if (socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd) < 0) { |
| fprintf(stderr, "socketpair: fail! errno = %d\n", errno); |
fprintf(ox_stderr, "socketpair: fail! errno = %d\n", errno); |
| } |
} |
| if (fork() == 0) { |
if (fork() == 0) { |
| /* child process */ |
/* child process */ |