EchoServer
そろそろ、実用的かどうかは別にして、これまでよりは大きいプログラムを書いてみようと思う。C言語で EchoServer を書く。C でSocketプログラミングする際の流れとしては、
- socket を開く
- bind で socket が使用するリスンアドレス、ポートを指定する
- listen して待ち受けスタート
- accept してクライアント Socket を受け入れ
- accept したクライアント Socket に対し、read、write等を使用してデータのやりとりをする
- close する
という流れになる。サンプルを書いてみた。こんな感じだろうか。
#include <stdio.h> #include <string.h> #include <netinet/in.h> #include <unistd.h> int main(int argc, char *args[]) { if (argc != 3) { printf("Usage: %s $ListenAddress $ListenPort\n", args[0]); return 1; } struct sockaddr_in server_addr; struct sockaddr_in client_addr; int listen_fd; int conn_fd; int rsize; char receive_buffer[1024]; // Passive Open if (( listen_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror("socket"); return 2; } // 0 clear server_addr structure bzero((char *)&server_addr, sizeof(server_addr)); // Initialize server socket structure and bind server socket server_addr.sin_family = PF_INET; server_addr.sin_addr.s_addr = INADDR_ANY; server_addr.sin_port = htons(8080); if ( bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0 ) { perror("bind"); return 3; } // Port Listen if ( listen(listen_fd, SOMAXCONN) < 0 ) { perror("listen"); return 4; } printf("Start Listening Port : %d...\n", 8080); // Accept Client connection request unsigned int len = sizeof(client_addr); if ( (conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &len )) < 0 ) { perror("accept"); return 5; } // Close Server Socket close(listen_fd); // Read client data do { rsize = recv(conn_fd, receive_buffer, 1024, 0); if ( rsize == 0 ) { // Disconnect from client break; } else if ( rsize == -1 ) { perror("recv"); return 6; } else { write(conn_fd, receive_buffer, rsize); } } while (1); // Close Client Socket if ( close(conn_fd) < 0 ) { perror("close"); return 7; } printf("Connection closed.\n"); return 0; }
コンパイル通るのは確認したが、通信できるかは確認していない。ちょっとずつこれを改良していって、本格的にしていきたい。次はクライアント書いてみるか。なお、この実装は[C言語]Socket間通信 echoサーバを作る « イイ!! プログラミング Blogをベースにさせていただきました。