#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 enum {CMD_NAME, DST_IP, DST_PORT}; int main(int argc, char *argv[]) { struct sockaddr_in server; /* サーバのアドレス */ unsigned long dst_ip; /* サーバのIPアドレス */ int port; /* ポート番号 */ 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); } /* サーバのIPアドレスを調べる */ if ((dst_ip = inet_addr(argv[DST_IP])) == INADDR_NONE) { struct hostent *he; /* ホスト情報 */ if ((he = gethostbyname(argv[DST_IP])) == NULL) { fprintf(stderr, "gethostbyname error\n"); exit(EXIT_FAILURE); } memcpy((char *)&dst_ip, (char *)he->h_addr, he->h_length); } /* サーバのポート番号を調べる */ if (argc == 3) { if ((port = atoi(argv[DST_PORT])) == 0) { struct servent *se; /* サービス情報 */ if ((se = getservbyname(argv[DST_PORT], "tcp")) != NULL) port = (int)ntohs((u_short)se->s_port); else { fprintf(stderr, "getservbyname error\n"); exit(EXIT_FAILURE); } } } else port = DEFAULT_PORT; /* TCPでソケットを開く */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { perror("socket"); exit(EXIT_FAILURE); } /* サーバのアドレスを設定しコネクションを確立する */ memset((char *) &server, 0, sizeof(server)); server.sin_family = AF_INET; server.sin_addr.s_addr = dst_ip; server.sin_port = htons(port); if (connect(s, (struct sockaddr *) &server, sizeof server) < 0) { perror("connect"); exit(EXIT_FAILURE); } printf("connected to '%s'\n", inet_ntoa(server.sin_addr)); /* クライアント処理メインルーチン */ 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); return EXIT_SUCCESS; }