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 */ |