EchoServerV4
EchoServerV4_alpha - Shammerismの実装を少し修正。accept の位置を変更。それから、サーバー側の Socket をクローズする箇所も想定通りの動作をさせるためには不適切だったのでこれも変更した。Version 4 の実装は以下。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <netinet/in.h> #include <unistd.h> #include <ctype.h> int checknumber(char *v){ int len = strlen(v); int i; int result = 1; for(i = 0; i < len && result ; i++){ result = isdigit(v[i]); } return result; } int main(int argc, char *args[]) { if (argc != 2) { printf("Usage: %s $ListenPort\n", args[0]); return 1; } if ( checknumber(args[1]) ){ struct sockaddr_in server_addr; struct sockaddr_in client_addr; int port = atoi(args[1]); 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(port); 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", port); // Read client data do { // 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; } rsize = recv(conn_fd, receive_buffer, 1024, 0); if ( rsize == 0 ) { // Disconnect from client printf("Client closed...\n"); } else if ( rsize == -1 ) { perror("recv"); return 6; } else { printf("Received Message:%s\n", receive_buffer); write(conn_fd, receive_buffer, rsize); if( strcmp( receive_buffer, "quit") == 0 ){ write(conn_fd, "EchoServer quit.\n", strlen("EchoServer quit.\n")); break; } } } while (1); // Close Server Socket close(listen_fd); // Close Client Socket if ( close(conn_fd) < 0 ) { perror("close"); return 7; } printf("Connection closed.\n"); return 0; } }
動作確認結果は以下。
$ ./eserver 10080 Start Listening Port : 10080... Received Message:Test Received Message:Test Received Message:Quit Received Message:quit Connection closed. $
期待通りっぽい。しかし、クライアント側でサーバーからの応答を表示するようになっていないので、今度はクライアントを書き換えて、サーバーから受け取ったメッセージを表示するようにしようと思う。クライアントでは名前解決して、ホスト名で接続できるようにもしたい。
$ ./eclient 127.0.0.1 10080 Test $ ./eclient 127.0.0.1 10080 Test $ ./eclient 127.0.0.1 10080 Test $ ./eclient 127.0.0.1 10080 Test $ ./eclient 127.0.0.1 10080 Test $ ./eclient 127.0.0.1 10080 Quit $ ./eclient 127.0.0.1 10080 quit $