やっとこさ本来の目的だったソケットに到着しました。
購入したのはもうずいぶんと前で、飲み会の時間つぶしに本屋さんに行ったときにおぉぉと思って買っておいた、TCP/IP Sockets in Cという本を翻訳したTCP/IPソケットプログラミングC言語編という書籍です。
サンプルコードを書きながら何をやっているかもわかるようになって、やっとこさってとこですね。最初はTCPのエコークライアント/サーバーですが、サンプルだけも面白くないので、ちょっと逸れてポート監視にしてみました。
ソース 4.29 インデントがおかしかったので修正
#include <stdio.h> // printf, fprintf, perror #include <netinet/in.h> // IPPROTO_TCP #include <sys/socket.h> // socket, connect, send, recv #include <arpa/inet.h> // sockaddr_in, inet_addr #include <stdlib.h> // atoi #include <string.h> // memset #include <unistd.h> // close #include <time.h> #define RCVBUFSIZE 32 #define CheckPortNUM 6 void DieWithError(char *errorMessage) // エラー処理 { perror(errorMessage); exit(1); } int main(int argc, char *argv[]) { int sock; // ソケットディスクリプタ struct sockaddr_in ServAddr; //サーバのアドレス int i = 0; int ServPort[CheckPortNUM] = {22, 25, 80, 110, 443, 995}; // チェックしたい対象ポート int ChPort; //代入の為のクッション変数 char *servIP; // サーバのIPアドレス if((argc < 2 || argc >= 3)) { fprintf(stderr, "Usage: %s <server IP><Echo Word>[<Echo Port>]\n", argv[0]); return 1; } servIP = argv[1]; // IPアドレスを取る /* ポート以外のサーバのアドレス構造体を作成 */ memset(&ServAddr, 0, sizeof(ServAddr)); //0で埋める ServAddr.sin_family = AF_INET; //アドレスファミリ ServAddr.sin_addr.s_addr = inet_addr(servIP); // IPアドレス while(i < CheckPortNUM){ /* TCPソケットを作成 */ if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) DieWithError("sokcet() failed"); ChPort = ServPort[i]; ServAddr.sin_port = htons(ChPort); //ポート番号 /*・サーバへの接続を確立する。*/ if(connect(sock, (struct sockaddr *)&ServAddr, sizeof(ServAddr)) == 0) printf("%d Port OK\n", ChPort); //戻り値が0ならListen else printf("%d Port NG\n", ChPort); i++; close(sock); } return 0; }
結果 複数
% ./TCPPortCheck 127.0.0.1 22 Port OK 25 Port OK 80 Port NG 110 Port NG 443 Port NG 995 Port NG $ ./TCPPortCheck 127.0.0.1 22 Port NG 25 Port OK 80 Port OK 110 Port NG 443 Port NG 995 Port NG 10022 Port OK 486 Port NG
名前解決もできないしタイムアウトもないので、プログラムに求められる・・・なんだっけ。何か忘れてしまったけど、使い道は広くはない。たとえば、何回か続けて同じポートでNGが出たらメール送信する!とかすれば使える感じかなぁ。
今使っている本番サーバーではシェルスクリプトで80番をGETしてステータスコードが200じゃなければreloadするという監視スクリプトが動いていますが、よく見れば今回作ったプログラムの方が色々と広げられそうですね。
使えるのか使えないのかどっちなんだ(笑)
まあいい。
この書籍ですが、学生向けの教科書らしく説明はかなり丁寧で、いままでの復習にもなるし、さらに詳しく知る事もできるようなものになっています。
まだ読みだしたとこですけど、今までブックマークしているウェブサイトとかも合わせて進めたいと思います。
また何か作ろう。
参考文献
TCP/IP ソケットプログラミングC言語編
小高知宏訳 Michael J. Donahoo/Kenneth L. Calvert共著