#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netdb.h> #include <sys/types.h> #include <sys/time.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define BUFSIZE 8192 #define DEFAULT_PORT "5320" #define CMAX 256 enum {CMD_NAME, DST_IP, DST_PORT}; int main(int argc, char *argv[]) { struct addrinfo info, *res; /* アドレス情報 */ char ip[CMAX]; /* IPアドレスを文字列として格納 */ int s; /* ソケットディスクリプタ */ int n; /* 入力データのバイト数 */ char buf[BUFSIZE]; /* 受信バッファ */ char cmd[BUFSIZE]; /* 送信バッファ */ struct timeval tv; /* selectのタイムアウト時間 */ fd_set readfd; /* selectで検出するディスクリプタ */ /* 引き数のチェック */ if (argc !=2 && argc != 3) { fprintf(stderr, "Usage: %s hostname [port]\n", argv[0]); exit(EXIT_FAILURE); } memset(&info, 0, sizeof(info)); info.ai_flags = AI_CANONNAME; info.ai_family = AF_UNSPEC; info.ai_socktype = SOCK_STREAM; if (getaddrinfo(argv[DST_IP], (argc == 3)?argv[DST_PORT]:DEFAULT_PORT, &info, &res) != 0) { perror("getaddrinfo"); exit(EXIT_FAILURE); } /* ソケットを開く */ if ((s = socket(res->ai_family, res->ai_socktype, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } /* コネクションを確立する */ if (connect(s, res->ai_addr, res->ai_addrlen) < 0) { perror("connect"); exit(EXIT_FAILURE); } if (res->ai_family == AF_INET6) printf("connected to '%s' by IPv6\n", inet_ntop(AF_INET6, &(((struct sockaddr_in6 *)(res->ai_addr))->sin6_addr), ip, CMAX)); else if (res->ai_family == AF_INET) printf("connected to '%s' by IPv4\n", inet_ntop(AF_INET, &(((struct sockaddr_in *)(res->ai_addr))->sin_addr), ip, CMAX)); else printf("connected by no IPv4/IPv6.\n"); /* クライアント処理メインルーチン */ while (1) { /* selectのタイムアウトの設定 */ tv.tv_sec = 600; tv.tv_usec = 0; /* 標準入力、サーバからのメッセージがあるか */ FD_ZERO(&readfd); FD_SET(0, &readfd); FD_SET(s, &readfd); if ((select(s + 1, &readfd, NULL, NULL, &tv)) <= 0) { fprintf(stderr, "\nTimeout\n"); break; } /* 標準入力 */ if (FD_ISSET(0, &readfd)) { if ((n = read(0, buf, BUFSIZE-1)) <= 0) break; buf[n]='\0'; sscanf(buf, "%s", cmd); if (strcmp(cmd, "quit") == 0) break; if (send(s, buf, n, 0) <= 0) break; } /* サーバ */ if (FD_ISSET(s, &readfd)) { if ((n = recv(s, buf, BUFSIZE-1, 0)) <= 0) { fprintf(stderr, "connection closed.\n"); exit(EXIT_FAILURE); } buf[n]='\0'; printf("%s", buf); fflush(stdout); } } strcpy(buf, "quit"); send(s, buf, n, 0); close(s); printf("connection closed.\n"); return EXIT_SUCCESS; }