ソケット通信
ソケット通信とは
ソケットとは、TCP/IPで通信を行なうコンピュータが持つネットワーク内での住所にあたるIPアドレスと、
IPアドレスのサブ(補助)アドレスであるポート番号を組み合わせたネットワークアドレスのこと。
通常、TCP/IP通信においては、1つのIPアドレスは複数(通常は65536個)の「ポート」から構成され、他のIPアドレス上のポートと結合して、
複数のアドレスと同時に通信できるようになっている。接続を行なう場合は必ずIPアドレスとポート番号の組を指定し、この組のことをソケットという。
1つのビル(IPアドレス)に複数の階(ポート)があり、どのビルのどの階かを指定して通信を行なうのがソケットであると言える。
ソケットには、通信を行なうアプリケーションソフトがTCP/IPを扱うための仮想的なインターフェースという意味もある。
C言語によるソケット通信
ネットワークを通して、データをやりとりするためには、Socketに対して、読み書きをします。
C言語による、Socket間通信は、下記のような手順になります。
1.socket() によりソケットを開く
2.bind() により、コネクションを受けつけるIPアドレス・ポート番号と ソケットとを対応づける
3.listen() によりクライアントからの接続待ち受け状態にする
4.accept() によりクライアントからの接続を受け付ける
5.read(), write(), send(), recv() などを用いて通信を行う
6.close() によりソケットを閉じる
分かりやすく例文のプログラミングにコメント付けまくって理解する事にする。
実際に文字列を単純にクライアントに返すだけのプログラム(echoサーバ)。
ちなみに、本コードでは、1回やりとりが終わると、サーバプロセスも終了します。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#define PORT 8823 /* Listenするポート */
#define MAXDATA 1024 /* 受信バッファサイズ */
int main(void)
{
struct sockaddr_in saddr; /* サーバ用アドレス格納構造体 */
struct sockaddr_in caddr; /* クライアント用アドレス格納構造体 */
int listen_fd;
int conn_fd;
int len = sizeof(struct sockaddr_in);
int rsize;
char buf[MAXDATA]; /* 受信バッファ */
/* ソケットの生成 */
if ((listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
/* saddrの中身を0にしておかないと、bind()でエラーが起こることがある */
bzero((char *)&saddr, sizeof(saddr));
/* ソケットにアドレスとポートを結びつける */
saddr.sin_family = PF_INET; /*プロトコルファミリ*/
saddr.sin_addr.s_addr = INADDR_ANY; /*IPアドレス INADDR_ANYはワイルドカード*/
saddr.sin_port = htons(PORT); /*ポート番号の指定*/
if (bind(listen_fd, (struct sockaddr *)&saddr,len) < 0) { /*構造体saddrの中身確認*/
perror("bind");
exit(EXIT_FAILURE);
}
/* ポートをListenする */
if (listen(listen_fd, SOMAXCONN) < 0) {
perror("listern");
exit(EXIT_FAILURE);
}
printf("Start Listening Port : %d...\n", PORT);
/* 接続要求を受け付ける */
if ((conn_fd = accept(listen_fd, (struct sockaddr *)&caddr, &len)) < 0) {
perror("accept");
exit(EXIT_FAILURE);
}
/* Listeningソケットを閉じる */
close(listen_fd);
/* 送信されたデータの読み出し */
do {
rsize = recv(conn_fd, buf, MAXDATA, 0);
if (rsize == 0) { /* クラアイントが接続を切ったとき */
break;
} else if (rsize == -1) {
perror("recv");
exit(EXIT_FAILURE);
}else {
write(conn_fd, buf, rsize);
}
} while (1);
if ( close(conn_fd) < 0) {
perror("close");
exit(EXIT_FAILURE);
}
printf("Connection closed.\n");
return 0;
}
最終更新:2010年02月25日 20:55