------------------------- c_setup.cpp ------------------------- /******************************************/ /* ソケットの初期設定(クライアント) */ /* return : ソケットのディスクリプタ */ /******************************************/ #include <stdio.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <netdb.h> // ソケット(hostent等) #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 #include <unistd.h> // fork, read, write, open, close //int c_setup(char *hostname, in_port_t port) int c_setup(char *hostname, int port) // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 { int client_socket = -1; // ソケット hostent *server_inf1; // サーバ情報1 sockaddr_in server_inf2; // サーバ情報2 /* サーバ名からサーバ情報を得る */ if ((server_inf1 = gethostbyname(hostname)) == NULL) printf("***error*** サーバ名が不適当です\n"); /* サーバ情報をsockaddr_in構造体に設定 */ else { memset((char *)&server_inf2, 0, sizeof(server_inf2)); server_inf2.sin_family = AF_INET; // アドレスファミリー server_inf2.sin_port = htons(port); // htons(2バイト) // 整数の上位及び下位バイトの指定 memcpy((char *)&server_inf2.sin_addr.s_addr, server_inf1->h_addr, server_inf1->h_length); /* ソケットを作成 */ if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("***error*** socketを作成できませんでした\n"); /* サーバへ接続 */ else { if (connect(client_socket, (sockaddr *)&server_inf2, sizeof(server_inf2)) == -1) client_socket = -1; } } return client_socket; } ------------------------- html.cpp (main) ------------------------- /****************************/ /* HTTPクライアント */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> // fork, read, write, open, close #include <netinet/in.h> // in_port_t, sockaddr_in等 #define BUF_LEN 512 // バッファサイズ #define PORT 80 // ポート番号 //int c_setup(char *, in_port_t); int c_setup(char *, int); // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 int main(int argc, char *argv[]) { int n; int client_socket; // 送受信用のソケット char buf[BUF_LEN]; // 送受信用バッファ char hostname[50] = "cs-www"; // ホスト名 char adr[100] = "/suganuma/index.html"; // ファイル名 char buf1[20]; /* 初期設定 */ if ((client_socket = c_setup(hostname, PORT)) == -1) { printf("***error*** 接続できませんでした\n"); exit(1); } /* サーバとの送信 */ else { // 送信内容の指定(サーバに対するリクエスト) strcpy(buf, "GET "); strcat(buf, adr); strcat(buf, " HTTP/1.1\r\n"); write(client_socket, buf, strlen(buf)); // ホスト名とポート strcpy(buf, "Host: "); strcat(buf, hostname); strcat(buf, ":"); gcvt((double)PORT, 10, buf1); strcat(buf, buf1); strcat(buf, "\r\n"); write(client_socket, buf, strlen(buf)); // リクエスト(GET)の終了 strcpy(buf, "\r\n"); write(client_socket, buf, strlen(buf)); // 受信内容の表示 n = 1; while (n > 0) { n = read(client_socket, buf, BUF_LEN); if (n > 0) write(1, buf, n); } } close(client_socket); return 0; }
クライアント側のプログラム
------------------------- c_setup.cpp ------------------------- /******************************************/ /* ソケットの初期設定(クライアント) */ /* hostname : サーバ名 */ /* port : ポート番号 */ /* return : ソケットのディスクリプタ */ /******************************************/ #include <stdio.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <netdb.h> // ソケット(hostent等) #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 int c_setup(char *hostname, in_port_t port) //int c_setup(char *hostname, int port) // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 { int client_socket = -1; // ソケット hostent *server_inf1; // サーバ情報1 sockaddr_in server_inf2; // サーバ情報2 /* サーバ名からサーバ情報を得る */ if ((server_inf1 = gethostbyname(hostname)) == NULL) printf("***error*** サーバ名が不適当です\n"); /* サーバ情報をsockaddr_in構造体に設定 */ else { memset((char *)&server_inf2, 0, sizeof(server_inf2)); server_inf2.sin_family = AF_INET; // アドレスファミリー server_inf2.sin_port = htons(port); // htons(2バイト) // 整数の上位及び下位バイトの指定 memcpy((char *)&server_inf2.sin_addr.s_addr, server_inf1->h_addr, server_inf1->h_length); /* ソケットを作成 */ if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("***error*** socketを作成できませんでした\n"); /* サーバへ接続 */ else { if (connect(client_socket, (sockaddr *)&server_inf2, sizeof(server_inf2)) == -1) client_socket = -1; } } /* ディスクリプタを返す */ return client_socket; } ------------------------- client1.cpp (main) ------------------------- /********************************/ /* ファイル転送(クライアント) */ /* coded by Y.Suganuma */ /********************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <fcntl.h> // O_RDONLY等 #include <unistd.h> // fork, read, write, open, close #include <netinet/in.h> // in_port_t, sockaddr_in等 #define BUF_LEN 512 // バッファサイズ #define PORT 50000 // ポート番号 int c_setup(char *, in_port_t); //int c_setup(char *, int); // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 int main(int argc, char *argv[]) { int n, sw, in; int client_socket; // 送受信用のソケット char buf[BUF_LEN]; // 送受信用バッファ char hostname[50]; // ホスト名 /* サーバ名 */ if (argc != 2) { printf("***error*** サーバ名を入力してください\n"); exit(1); } else strcpy(hostname, argv[1]); /* 初期設定 */ if ((client_socket = c_setup(hostname, PORT)) == -1) { printf("***error*** 接続できませんでした\n"); exit(1); } /* ファイル名の入力とファイル内容の転送 */ // ファイル名の入力 n = read(client_socket, buf, BUF_LEN); write(1, buf, n); scanf("%s", buf); // ファイル名の送信 in = open(buf, O_RDONLY); // in = open(buf, O_BINARY | O_RDONLY); // OS(MS-DOSなど)によっては,上の行の代わりにこの行を使用しないと // バイナリファイルを正しく送信できない. if (in < 0) { printf("***error*** ファイルが存在しません\n"); close(client_socket); exit(1); } write(client_socket, buf, strlen(buf)+1); // ファイル内容の送信 sw = 1; while (sw > 0) { n = read(in, buf, BUF_LEN); if (n > 0) write(client_socket, buf, n); else sw = 0; } /* 接続を切り,ファイルを閉じる */ close(client_socket); close(in); return 0; }
サーバ側のプログラム
------------------------- s_setup.cpp ------------------------- /************************************/ /* ソケットの初期設定(サーバ) */ /* port : ポート番号 */ /* return : リスニングソケット */ /************************************/ #include <stdio.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/socket.h> // ソケット(AF_INET, select等) #include <arpa/inet.h> // ソケット(sockaddr_in等) #include <netinet/in.h> // in_port_t, sockaddr_in等 int s_setup(in_port_t port) //int s_setup(int port) // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 { int listening_socket = -1; // リスニングソケット sockaddr_in server_inf; // サーバ情報 /* サーバ情報をsockaddr_in構造体に設定 */ memset((char *)&server_inf, 0, sizeof(server_inf)); server_inf.sin_family = AF_INET; // アドレスファミリー server_inf.sin_addr.s_addr = htonl(INADDR_ANY); // IPアドレス server_inf.sin_port = htons(port); // htonl(4バイト),htons(2バイト) // 整数の上位及び下位バイトの指定 /* リスニングソケットを作成 */ if ((listening_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("***error*** 接続できませんでした\n"); /* サーバのアドレスをソケットに設定する */ else { if (bind(listening_socket, (sockaddr *)&server_inf, sizeof(server_inf)) < 0) printf("***error*** 設定に失敗しました\n"); /* 待ち受ける(待機状態の準備)(第2引数は,待ち受けの数) */ else { if (listen(listening_socket, 1) == -1 ) printf("***error*** 待ち受けに失敗しました\n"); } } return listening_socket; } ------------------------- e_ftp.cpp ------------------------- /********************************************/ /* ftpの実行 */ /* connected_socket : 接続済みソケット */ /********************************************/ #include <stdio.h> #include <fcntl.h> // O_RDONLY等 #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netdb.h> // ソケット(inet_ntoa等) #include <arpa/inet.h> // ソケット(sockaddr_in等) #include <unistd.h> // fork, read, write, open, close #include <netinet/in.h> // in_port_t, sockaddr_in等 #define BUF_LEN 512 // バッファサイズ void e_ftp(int connected_socket) { int n, sw, out; char buf[BUF_LEN]; // 送受信用バッファ hostent *client_inf1; // クライアント情報1 sockaddr_in client_inf2; // クライアント情報2 socklen_t len; // int len; // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 /* クライアント情報を取得できた場合,それを表示する */ len = (socklen_t)sizeof(client_inf2); // len = sizeof(client_inf2); // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 getpeername(connected_socket, (sockaddr *)&client_inf2, &len); client_inf1 = gethostbyaddr((char *)&client_inf2.sin_addr.s_addr, sizeof(client_inf2.sin_addr), AF_INET); if (client_inf1 != NULL) { printf("%s と接続しました(IP: %s, ポート %d)\n", client_inf1->h_name, inet_ntoa(client_inf2.sin_addr), ntohs(client_inf2.sin_port)); } /* 送られてきたファイルを保存 */ // ファイル名 write(connected_socket, "ファイル名を入力してください ", 29); read(connected_socket, buf, BUF_LEN); // 保存 out = open(buf, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); // out = open(buf, O_BINARY | O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); // OS(MS-DOSなど)によっては,上の行の代わりにこの行を使用しないと, // バイナリファイルを正しく送信できない. sw = 1; while (sw > 0) { n = read(connected_socket, buf, BUF_LEN); if (n > 0) write(out, buf, n); else sw = 0; } close(out); } ------------------------- server1.cpp (main) ------------------------- /****************************/ /* ファイル転送(サーバ) */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 #include <unistd.h> // fork, read, write, open, close #define PORT 50000 // ポート番号 int s_setup(in_port_t); //int s_setup(int); // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 void e_ftp(int); int main() { int listening_socket; // リスニングソケット int connected_socket; // 接続済みソケット pid_t pid; // プロセスID /* リスニングソケットの生成 */ if ((listening_socket = s_setup(PORT)) != -1) { /* 接続待機 */ while(1) { // 接続済みソケット if ((connected_socket = accept(listening_socket, NULL, NULL)) != -1) { // 子プロセスの生成 // 子プロセス if ((pid = fork()) == 0) { close(listening_socket); e_ftp(connected_socket); close(connected_socket); exit(0); } // 親プロセス else close(connected_socket); } } } return 0; }
クライアント側のプログラム
------------------------- c_setup.cpp ------------------------- /******************************************/ /* ソケットの初期設定(クライアント) */ /* hostname : サーバ名 */ /* port : ポート番号 */ /* return : ソケットのディスクリプタ */ /******************************************/ #include <stdio.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <netdb.h> // ソケット(hostent等) #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 int c_setup(char *hostname, in_port_t port) //int c_setup(char *hostname, int port) // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 { int client_socket = -1; // 送受信用のソケット hostent *server_inf1; // サーバ情報1 sockaddr_in server_inf2; // サーバ情報2 /* サーバ名からサーバ情報を得る */ if ((server_inf1 = gethostbyname(hostname)) == NULL) printf("***error*** サーバ名が不適当です\n"); /* サーバ情報をsockaddr_in構造体に設定 */ else { memset((char *)&server_inf2, 0, sizeof(server_inf2)); server_inf2.sin_family = AF_INET; // アドレスファミリー server_inf2.sin_port = htons(port); // htons(2バイト) // 整数の上位及び下位バイトの指定 memcpy((char *)&server_inf2.sin_addr.s_addr, server_inf1->h_addr, server_inf1->h_length); /* ソケットを作成 */ if ((client_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("***error*** socketを作成できませんでした\n"); /* サーバへ接続 */ else { if (connect(client_socket, (sockaddr *)&server_inf2, sizeof(server_inf2)) == -1) client_socket = -1; } } /* ディスクリプタを返す */ return client_socket; } ------------------------- prepare.cpp ------------------------- /***************************************/ /* 会話のための準備 */ /* soc : ソケットのディスクリプタ */ /* return : select用初期化マスク */ /***************************************/ #include <sys/types.h> // fd_set #include <string.h> // 文字列操作,memset,FD_ZERO等 fd_set prepare(int soc) { fd_set mask; /* マスクの準備 */ FD_ZERO(&mask); FD_SET(0, &mask); // ディスクリプタ0(キーボード)をセット FD_SET(soc, &mask); // ソケットのディスクリプタをセット return mask; } ------------------------- chat.cpp ------------------------- /**************************************/ /* 会話 */ /* fd : ソケットのディスクリプタ */ /* buf : バッファ */ /* size : バッファサイズ */ /* mask : select用初期化マスク */ /**************************************/ #include <stdio.h> #include <sys/types.h> // fd_set #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/socket.h> // ソケット(AF_INET, select等) #include <unistd.h> // fork, read, write, open, close void chat(int fd, char *buf, int size, fd_set mask) { int n, sw = 1; fd_set now; while (sw > 0) { // マスクの初期化 now = mask; select(fd+1, (fd_set*)&now, NULL, NULL, NULL); // キーボードからの入力チェック if (FD_ISSET(0, &now)) { gets(buf); n = strlen(buf); if (n > 0) write(fd, buf, n); // 送信 } // ソケット内のデータを調べる if (FD_ISSET(fd, &now)) { n = read(fd, buf, size); buf[n] = '\0'; if (strcmp(buf, "Server.quit") == 0) { printf("チャットルームを閉じます!\n"); close(fd); sw = 0; } else if (strcmp(buf, "quit") == 0) { close(fd); sw = 0; } else write(1, buf, n); } } } ------------------------- client2.cpp (main) ------------------------- /**********************************/ /* チャットルーム(クライアント) */ /* coded by Y.Suganuma */ /**********************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> // fd_set #include <unistd.h> // fork, read, write, open, close #include <netinet/in.h> // in_port_t, sockaddr_in等 #define BUF_LEN 512 // バッファサイズ #define PORT 50000 // ポート番号 void chat(int, char *, int, fd_set); fd_set prepare(int); int c_setup(char *, in_port_t); //int c_setup(char *, int); // コンパイラのバージョンによっては, // 上の行の代わりにこの行を使用 int main(int argc, char *argv[]) { int n; int client_socket; // 送受信用のソケット char buf[BUF_LEN]; // 送受信用バッファ char hostname[50]; // ホスト名 fd_set mask; // 相手を選択する(select)ための初期化マスク /* サーバ名 */ if (argc != 2) { printf("***error*** サーバ名を入力してください\n"); exit(1); } else strcpy(hostname, argv[1]); /* 初期設定 */ if ((client_socket = c_setup(hostname, PORT)) == -1) { printf("***error*** 接続できませんでした\n"); exit(1); } /* 参加登録 */ n = read(client_socket, buf, BUF_LEN); // 参加者名の入力を促すメッセージ write(1, buf, n); buf[n] = '\0'; if (strstr(buf, "満員ですので,後ほどご利用下さい") != NULL) close(client_socket); else { gets(buf); // 参加者名の入力 write(client_socket, buf, strlen(buf)+1); n = read(client_socket, buf, BUF_LEN); // 「しばらくお待ち下さい」 write(1, buf, n); // サーバとクライアントが会話を行うための準備(マスクの設定) mask = prepare(client_socket); // チャットの実行 chat(client_socket, buf, BUF_LEN, mask); } return 0; }
サーバ側のプログラム
------------------------- member.h ------------------------- /**************/ /* 参加者情報 */ /**************/ class Member { public: int state; // 回線の状態(1 : 開, 0 : 閉) int fd; // ソケットディスクリプタ char name[50]; // 参加者名 Member(); // コンストラクタ }; ------------------------- Member.cpp ------------------------- /********************************/ /* クラスmemberのコンストラクタ */ /********************************/ #include "member.h" Member::Member() { state = 0; } ------------------------- s_setup.cpp ------------------------- /************************************/ /* ソケットの初期設定(サーバ) */ /* port : ポート番号 */ /* w_no : 待ち受けの最大数 */ /* return : リスニングソケット */ /************************************/ #include <stdio.h> #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 int s_setup(in_port_t port, int w_no) //int s_setup(int port, int w_no) // コンパイラのバージョンによっては,上の行の代わりにこの行を使用 { int listening_socket = -1; // リスニングソケットソケット sockaddr_in server_inf; // サーバ情報 /* サーバ情報をsockaddr_in構造体に設定 */ memset((char *)&server_inf, 0, sizeof(server_inf)); server_inf.sin_family = AF_INET; // アドレスファミリー server_inf.sin_addr.s_addr = htonl(INADDR_ANY); // IPアドレス server_inf.sin_port = htons(port); // htonl(4バイト),htons(2バイト) // 整数の上位及び下位バイトの指定 /* リスニングソケットを作成 */ if ((listening_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) printf("***error*** 接続できませんでした\n"); /* サーバのアドレスをソケットに設定する */ else { if (bind(listening_socket, (sockaddr *)&server_inf, sizeof(server_inf)) < 0) printf("***error*** 設定に失敗しました\n"); /* 待ち受ける(待機状態の準備)(第2引数は,待ち受けの数) */ else { if (listen(listening_socket, w_no) == -1 ) printf("***error*** 待ち受けに失敗しました\n"); } } return listening_socket; } ------------------------- init.cpp ------------------------- /************************************/ /* 参加者の登録と初期設定 */ /* soc : 接続済みソケット */ /* w_no : 待ち受けの最大数 */ /* mask : select用初期化マスク */ /* no : 現在の接続数 */ /* mem : 接続登録簿 */ /* return : 現在の接続数 */ /************************************/ #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/types.h> // fd_set #include <unistd.h> // read, write, open, close #include "member.h" int init(int soc, int w_no, fd_set *mask, int no, Member **mem) { int i1, sw = 0; // 満員 if (no == w_no) { write(soc, "満員ですので,後ほどご利用下さい\n", 33); close(soc); } // 参加できる else { for (i1 = 0; i1 < w_no && sw == 0; i1++) { if (mem[i1]->state == 0) { // ディスクリプタの登録 mem[i1]->state = 1; mem[i1]->fd = soc; no++; // マスクの設定 FD_SET(mem[i1]->fd, mask); // 参加者名 write(soc, "名前を入力して下さい ", 21); read(soc, mem[i1]->name, 50); strcat(mem[i1]->name, ": "); // 開始OK write(soc, "しばらくお待ち下さい\n", 21); write(soc, "チャット開始OKです!\n", 23); sw = 1; } } } return no; } ------------------------- chat.cpp ------------------------- /**********************************************/ /* チャットの実行 */ /* w_no : 待ち受けの最大数 */ /* max_fd : ソケットの最大ディスクリプタ */ /* buf : バッファ */ /* size : バッファサイズ */ /* mask : select用初期化マスク */ /* no : 現在の接続数 */ /* mem : 各ソケットの状態 */ /* listening_socket : リスニングソケット */ /**********************************************/ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> // fd_set #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/socket.h> // ソケット(AF_INET, select等) #include <unistd.h> // read, write, open, close #include "member.h" #define BUF_LEN_TMP 562 // バッファの大きさ int init(int, int, fd_set *, int, Member **); int chat(int w_no, int *max_fd, char *buf, int size, fd_set *mask, int no, Member **mem, int listening_socket) { int i1, i2, k, len, n, sw = 1; char str[BUF_LEN_TMP]; int connected_socket; // 接続済みソケット fd_set now; // マスクの初期化と事象の選択 now = *mask; select((*max_fd)+1, (fd_set *)&now, NULL, NULL, NULL); // 新規のクライアント登録 if (FD_ISSET(listening_socket, &now)) { if ((connected_socket = accept(listening_socket, NULL, NULL)) != -1) { k = init(connected_socket, w_no, mask, no, mem); if (k > no) { no = k; if (connected_socket > *max_fd) *max_fd = connected_socket; } } else { printf("***error*** クライアントとの接続に失敗しました\n"); exit(1); } } // チャットの終了チェック if (FD_ISSET(0, &now)) { // キーボードからの入力チェック gets(buf); if (strcmp(buf, "quit") == 0) { for (i1 = 0; i1 < w_no; i1++) { if (mem[i1]->state > 0) write(mem[i1]->fd, "Server.quit", 11); } for (i1 = 0; i1 < w_no; i1++) { if (mem[i1]->state > 0) close(mem[i1]->fd); } for (i1 = 0; i1 < w_no; i1++) delete [] mem[i1]; delete [] mem; sw = 0; no = -1; } } // 各ソケットを調べる if (sw > 0) { for (i1 = 0; i1 < w_no; i1++) { if (mem[i1]->state > 0 && FD_ISSET(mem[i1]->fd, &now)) { n = read(mem[i1]->fd, buf, size); buf[n] = '\0'; // クライアントの終了 if (strcmp(buf, "quit") == 0) { write(mem[i1]->fd, "また参加して下さい!\n", 21); write(mem[i1]->fd, "quit", 4); FD_CLR(mem[i1]->fd, mask); close(mem[i1]->fd); mem[i1]->state = 0; *max_fd = -1; for (i2 = 0; i2 < w_no; i2++) { if (mem[i2]->state > 0 && mem[i2]->fd > *max_fd) *max_fd = mem[i2]->fd; } no--; } // チャットの続行 else { len = strlen(mem[i1]->name); strcpy(str, mem[i1]->name); strcat(str, buf); strcat(str, "\n"); for (i2 = 0; i2 < w_no; i2++) { if (mem[i2]->state > 0) write(mem[i2]->fd, str, n+len+1); } } } } } return no; } ------------------------- server2.cpp (main) ------------------------- /****************************/ /* チャットルーム(サーバ) */ /* coded by Y.Suganuma */ /****************************/ #include <stdio.h> #include <stdlib.h> // atoi等 #include <string.h> // 文字列操作,memset,FD_ZERO等 #include <sys/types.h> // fd_set #include <sys/socket.h> // ソケット(AF_INET, select等) #include <netinet/in.h> // in_port_t, sockaddr_in等 #include <unistd.h> // read, write, open, close #include "member.h" #define PORT 50000 // ポート番号 #define BUF_LEN 512 // バッファの大きさ int chat(int, int *, char *, int, fd_set *, int, Member **, int); int s_setup(in_port_t, int); //int s_setup(int, int); // コンパイラのバージョンによっては,上の行の代わりにこの行を使用 int main(int argc, char *argv[]) { int i1, no = 0, max = 0, sw = 1; char buf[BUF_LEN]; // バッファ int listening_socket; // リスニングソケットソケット int max_fd; // 接続済みソケットの最大ディスクリプタ fd_set mask; Member **mem; /* 最大参加者数 */ if (argc != 2) { printf("***error*** 参加者数を入力してください\n"); exit(1); } else max = atoi(argv[1]); /* リスニングソケットの準備 */ if ((listening_socket = s_setup(PORT, max)) == -1) { printf("***error*** リスニング接続に失敗しました\n"); exit(1); } /* 参加登録簿とマスクの準備 */ mem = new Member * [max]; for (i1 = 0; i1 < max; i1++) mem[i1] = new Member; max_fd = listening_socket; FD_ZERO(&mask); FD_SET(0, &mask); // ディスクリプタ0(キーボード)をセット FD_SET(listening_socket, &mask); // リスニングソケットをセット /* チャットの実行 */ printf("Ready to Chat\n"); while (sw > 0) { no = chat(max, &max_fd, buf, BUF_LEN, &mask, no, mem, listening_socket); if (no < 0) { sw = 0; close(listening_socket); } } return 0; }