メモ - ソケット通信について
|
/* */ /* コネクション型のサーバプログラム (hellosv.c) */ /* Usage: hellosv host_name & */ /* */ #include <stdio.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PROT_NO 5001 static char mesg[] = "Hello world."; static struct sockaddr_in sv_addr; /* サーバアドレス */ static struct sockaddr_in cl_addr; /* クライアントアドレス */ static struct hostent *sv_ip; /* サーバIPアドレス */ static int sid1; /* デーモンソケット識別子 */ static int sid2; /* 子プロセスソケット識別子 */ static int cl_size; /* クライアントアドレスサイズ */ /* サーバメイン */ main(argc, argv) int argc; char *argv[]; /* argv[1]:サーバホスト名 */ { int rtn; /* 返却値 */ /* 第一引数が省略されている場合はエラーとする。 */ if(&argv[1][0] == 0x00) { perror("argv[1]"); exit(1); } /* コネクション型ソケットの作成 (socket) */ sid1 = socket(AF_INET, SOCK_STREAM, 0); if (sid1 < 0) { perror("sv:socket"); goto err; } /* サーバのIPアドレスを取得 */ sv_ip = gethostbyname(argv[1]); if (sv_ip == NULL) { perror("sv:gethostbyname"); goto err; } /* ソケットに名前を付加 (bind) */ bzero((char *)&sv_addr, sizeof(sv_addr)); sv_addr.sin_family = AF_INET; sv_addr.sin_port = htons(PROT_NO); memcpy((char *)&sv_addr.sin_addr, (char *)sv_ip->h_addr, sv_ip->h_length); rtn = bind(sid1, &sv_addr, sizeof(sv_addr)); if (rtn < 0) { perror("sv:bind"); goto err; } /* クライアントからの接続要求の受付 (listen) */ rtn = listen(sid1, 5); if (rtn == -1) { perror("sv:listen"); goto err; } while (1) { /* クライアントからの接続要求の受信 (accept) */ cl_size = sizeof(cl_addr); sid2 = accept(sid1, &cl_addr, &cl_size); if (sid2 < 0) { perror("sv:accept"); goto err; } /* メッセージ通信処理 (send/recv) */ rtn = send(sid2, mesg, sizeof(mesg), 0); if (rtn < 0) perror("sv:send"); /* ソケットの開放 (shutdown,close) */ rtn = shutdown(sid2, 2); if (rtn < 0) perror("sv:shutdown"); close(sid2); } err: /* ソケットの開放 (close) */ close(sid1); exit(0); } |
/* */ /* コネクション型クライアントプログラム (hellocl.c) */ /* Usage: hellocl host_name */ /* */ #include <stdio.h> #include <netdb.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #define PROT_NO 5001 /* ポート番号 */ #define BUF_MAX 64 /* 通信バッファサイズ */ static struct sockaddr_in sv_addr; /* サーバアドレス */ static struct hostent *sv_ip; /* サーバIPアドレス */ static int sid; /* ソケット識別子 */ static char buf[BUF_MAX]; /* 通信バッファ */ /* クライアントメイン */ main(argc, argv) int argc; char *argv[]; /* argv[1]:サーバホスト名 */ { int rtn; /* 返却値 */ /* 第一引数が省略されている場合はエラーとする。 */ if(&argv[1][0] == 0x00) { perror("argv[1]"); exit(1); } /* コネクション型ソケットの作成 (socket) */ sid = socket(AF_INET, SOCK_STREAM, 0); if (sid < 0) { perror("cl:socket"); exit(1); } /* サーバのIPアドレスを取得 */ sv_ip = gethostbyname(argv[1]); if (sv_ip == NULL) { perror("cl:gethostbyname"); exit(1); } /* ソケットの接続要求 (connect) */ bzero((char *)&sv_addr, sizeof(sv_addr)); sv_addr.sin_family = AF_INET; sv_addr.sin_port = htons(PROT_NO); memcpy((char *)&sv_addr.sin_addr, (char *)sv_ip->h_addr, sv_ip->h_length); rtn = connect(sid, &sv_addr, sizeof(sv_addr)); if (rtn < 0) { perror("cl:connect"); close(sid); exit(1); } /* メッセージ通信処理 (send/recv) */ rtn = recv(sid, buf, BUF_MAX, 0); if (rtn < 0) perror("cl:recv"); printf("%s\n", buf); /* ソケットの開放 (shutdown/close) */ rtn = shutdown(sid, 2); if (rtn < 0) perror("cl:shutdown"); close(sid); exit(0); } |
all: hellosv hellocl clean: rm -f hellosv hellocl *.o hellosv: hellosv.c cc -o hellosv hellosv.c -lnsl hellocl: hellocl.c cc -o hellocl hellocl.c -lnsl |
動作確認 | TurboLinux6.1 Server |
戻る |
http://homepage2.nifty.com/~koji-hp/2013/memo/20020811.html
初版:2003.02.23 更新:2005.6.27(一部改良) 更新:2013.7.2(リニューアル) |