TCPを使う(2)
前述したTCPサーバ例は必要最低限の機能しかありませんでした。 必要最低限だけでは、色々と不具合があります。 例えば、前述したTCPサーバ例では一度クライアントと接続すると終了してしまいます。 ここでは、サーバとして何回もクライアントからの要求を受け付けられるようにTCPサーバ例を改造したいと思います。
何回もクライアントと接続できるサーバ例
一般的なTCPを使ったサーバは、複数回クライアントからの接続を受け付けます。 前述した単純なTCPサーバ例では、一度クライアントからの接続を受け付けたら終了してしまうので、全く実用性はありません。 ここでは、まず、手始めに複数回クライアントからの接続を受け付けられるサーバを作ってみたいと思います。
以下に改造したTCPサーバを示します。
#include <winsock2.h>
int
main()
{
WSADATA wsaData;
SOCKET sock0;
struct sockaddr_in addr;
struct sockaddr_in client;
int len;
SOCKET sock;
WSAStartup(MAKEWORD(2,0), &wsaData);
sock0 = socket(AF_INET, SOCK_STREAM, 0);
addr.sin_family = AF_INET;
addr.sin_port = htons(12345);
addr.sin_addr.S_un.S_addr = INADDR_ANY;
bind(sock0, (struct sockaddr *)&addr, sizeof(addr));
listen(sock0, 5);
while (1) {
len = sizeof(client);
sock = accept(sock0, (struct sockaddr *)&client, &len);
send(sock, "HELLO", 5, 0);
closesocket(sock);
}
WSACleanup();
return 0;
}
今回の改造は、while(1)部分だけです。 この改造により、前述した単純なTCPクライアントからの接続要求を複数回受け付けられるようになります。
この改造のポイントとして、今回の改造を行った場所と行っていない場所に注目して下さい。
今回改造を行わなかった場所は、「一度だけ行えば良い」部分です。 一度だけ行えば良い部分とは、クライアントからの接続要求を受け付ける準備をする部分です。
逆に、今回改造を行ったwhile(1)で囲まれた部分は、「TCPクライアントのセッション毎の処理」を表しています。 毎回、単純なTCPクライアントからの接続要求を受け付けて、文字列を送信して、クライアントとのセッションを終了するという処理がこのwhile(1)の中に含まれています。
今回の改造は非常にコードとしては小さいものですが、コード全体が持つ意味は大きく変わっています。 このサンプルを見てTCPセッションを受け付けるための準備と個々のTCPセッションの違いを理解して頂ければ幸いです。