|
メモ - ソケット通信について
|
|
|
/* */
/* コネクション型のサーバプログラム (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(リニューアル) |