特に驚くこともない、面白みのないプログラムのように思えますが、この単純なプログラムにはシステムプログラミングやネットワークプログラミングに必要なエレメントが詰まっています(と、思います)
おおまかな流れとしては
- ソケット(クライアントからの接続を受け付ける窓口のようなもの)をつくる
- ソケットを初期化する
- クライアントが繋いでくるのを待ち、接続を確立する
- クライアントから送られてきた文字列データを読み取る
- 読み取ったデータと全く同じものをクライアントの標準出力へ書き込む
- 接続を終了する
といったかんじです
それでは、実際にソースコードを見てみましょう
解答例:echo_server.c
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <netinet/in.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
int
main()
{
int sockfd, acceptfd;
int len;
char buf[1024];
struct sockaddr_in server, client;
/* ソケットを作る */
sockfd = socket(PF_INET, SOCK_STREAM, 0);
/* ソケットを初期化する */
memset(&server, 0, sizeof(server));
server.sin_family = PF_INET;
server.sin_port = htons(7000);
server.sin_addr.s_addr = htonl(INADDR_ANY);
bind(sockfd, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
/* クライアントからの接続を待つ */
listen(sockfd, 5);
/* クライアントとの接続を確立する*/
memset(&client, 0, sizeof(client));
len = sizeof(client);
acceptfd = accept(sockfd, (struct sockaddr*)&client, &len);
/* データを読み込む */
read (acceptfd, buf, sizeof(buf));
printf("accept data: %s\n", buf);
/* データを書き込む */
write (acceptfd, buf, strlen(buf));
/* 接続を閉じる */
close(acceptfd);
close(sockfd);
return (0);
}
ちなみに、インクルードファイルそれぞれが何のために必要かを示すと……
<sys/types.h> → socket(), listen(), accept(), read(), write()
<sys/socket.h> → socket(), listen(), accept(), read(), write()
<sys/uio.h>, <unistd.h> → read(), write()
<netinet/in.h> → struct sockaddr_in
<string.h> → memset()
上記のようになります
動作を確認するには、上のソースコードをコンパイルして生成された実行ファイルを起動した後、同じマシン上で
telnet localhost 7000
と打ち込み、telnetを起動すれば、echoサーバーとの接続が確立されます
動作を確認するには、上のソースコードをコンパイルして生成された実行ファイルを起動した後、同じマシン上で
telnet localhost 7000
と打ち込み、telnetを起動すれば、echoサーバーとの接続が確立されます
0 件のコメント:
コメントを投稿