質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

Q&A

0回答

2206閲覧

select関数によるI/Oの多重化のサーバプログラム作成について

chiko.unagi

総合スコア13

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

ソケット

TCP/IPにおいて、IPアドレスとサブアドレスであるポート番号を組み合わせたネットワークアドレスのことを呼びます。また、ソフトウェアアプリケーションにおいて、TCP/IP通信を行う為の仮想的なインターフェースという意味もある。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

サーバ

サーバは、 クライアントサーバモデルにおいてクライアントからの要求に対し 何らかのサービスを提供するプログラムを指す言葉です。 また、サーバーソフトウェアを稼動させているコンピュータ機器そのもののことも、 サーバーと呼ぶ場合もあります。

1グッド

0クリップ

投稿2020/05/12 07:32

編集2020/05/12 07:46

前提・実現したいこと

select関数を用いて同期I/Oの多重化を検証する課題を行っています。
単純なechoback関数を用いて通信のやり取りを行うのですが、今サーバー側プログラムの
制作で詰まっています。
以下echoback処理のサーバー側のサンプルプログラムとクライアント側のプログラム、そして今回使うselect関数によるデータ通信プログラムを掲載してあります。

発生している問題・エラーメッセージ

改めて困っている内容は、サンプルではselect関数を用いた通信プログラムの下のほうでechoback関数を使っているのですが、そのechoback関数の実装ないので方法を知りたいです。
簡潔に言うと以下のserver.cを参考にselect.cのechoback関数を実装したいというところでしょうか。

server.c

1 #include "exp1.h" 2 #include "exp1lib.h" 3 4 int main(int argc, char** argv) { 5 int sock_listen; 6 int sock_client; 7 struct sockaddr addr; 8 int len = 0; 9 int ret = 0; 10 char buf[1024]; 11 12 sock_listen = exp1_tcp_listen(11111); 13 sock_client = accept(sock_listen, &addr, (socklen_t*) &len); 14 ret = recv(sock_client, buf, 1024, 0); 15 write(1, buf, ret); 16 send(sock_client, buf, ret, 0); 17 close(sock_client); 18 close(sock_listen); 19 20 return 0; 21 }

client.c

1 #include "exp1.h" 2 #include "exp1lib.h" 3 4 int main(int argc, char** argv) { 5 int sock; 6 char* p; 7 char buf[1024]; 8 int ret; 9 10 if(argc != 2) { 11 printf("usage: %s [ip address]\n", argv[0]); 12 exit(-1); 13 } 14 15 sock = exp1_tcp_connect(argv[1], 11111); 16 p = fgets(buf, 1024, stdin); 17 send(sock, p, strlen(p), 0); 18 ret = recv(sock, buf, sizeof(buf), 0); 19 write(1, buf, ret); 20 close(sock); 21 22 return 0; 23 }

select.c

1#define MAXCHILD 1200 2void acceptLoop(int sock) { 3 4 // クライアント管理 5 int childNum = 0; 6 int child[MAXCHILD]; 7 int i = 0; 8 for (i = 0; i < MAXCHILD; i++) { 9 child[i] = -1; 10 } 11 12 while (true) { 13 14 // select用マスクの初期化 15 fd_set mask; 16 FD_ZERO(&mask); 17 FD_SET(sock, &mask); 18 int width = sock + 1; 19 int i = 0; 20 for (i = 0; i < childNum; i++) { 21 if (child[i] != -1) { 22 FD_SET(child[i], &mask); 23 if ( width <= child[i] ) { 24 width = child[i] + 1; 25 } 26 } 27 } 28 29 // マスクを設定 30 fd_set ready = mask; 31 32 // タイムアウト値のセット 33 struct timeval timeout; 34 timeout.tv_sec = 600; 35 timeout.tv_usec = 0; 36 37 switch (select(width, (fd_set *) &ready, NULL, NULL, &timeout)) { 38 case -1: 39 // エラー処理 40 perror("select"); 41 break; 42 case 0: 43 // タイムアウト 44 break; 45 default: 46 // I/Oレディあり 47 48 if (FD_ISSET(sock, &ready)) { 49 // サーバソケットレディの場合 50 struct sockaddr_storage from; 51 socklen_t len = sizeof(from); 52 int acc = 0; 53 if ((acc = accept(sock, (struct sockaddr *) &from, &len)) 54 == -1) { 55 // エラー処理 56 if (errno != EINTR) { 57 perror("accept"); 58 } 59 } else { 60 // クライアントからの接続が行われた場合 61 char hbuf[NI_MAXHOST]; 62 char sbuf[NI_MAXSERV]; 63 getnameinfo((struct sockaddr *) &from, len, hbuf, 64 sizeof(hbuf), sbuf, sizeof(sbuf), 65 NI_NUMERICHOST | NI_NUMERICSERV); 66 fprintf(stderr, "accept:%s:%s\n", hbuf, sbuf); 67 68 // クライアント管理配列に登録 69 int pos = -1; 70 int i = 0; 71 for (i = 0; i < childNum; i++) { 72 if (child[i] == -1) { 73 pos = i; 74 break; 75 } 76 } 77 78 if (pos == -1) { 79 if (childNum >= MAXCHILD) { 80 // 並列数が上限に達している場合は切断する 81 fprintf(stderr, "child is full.\n"); 82 close(acc); 83 } else { 84 pos = childNum; 85 childNum = childNum + 1; 86 } 87 } 88 89 if (pos != -1) { 90 child[pos] = acc; 91 } 92 } 93 } 94 95 // アクセプトしたソケットがレディの場合を確認する 96 int i = 0; 97 for (i = 0; i < childNum; i++) { 98 if (child[i] != -1 && FD_ISSET(child[i], &ready)) { 99 // クライアントとの通信処理 100 if ( echoBack(child[i]) == false ) { 101 close(child[i]); 102 child[i] = -1; 103 } 104 } 105 } 106 } 107 } 108}
mit0223👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/05/12 07:37

// エコーバックを行う(echoBack関数は自分で作成すること) って指示されています。 指示に従い、自分で作成してください。
episteme

2020/05/12 07:54

そもそも 関数 echoBack() が何をするかが示されていないので答えようがありません。
jimbe

2020/05/13 03:34

ご質問を編集してわざわざ episteme さんの指摘されたコメントを削除されているのは, どういう意図でしょうか. 課題を質問したことを隠すためであれば, 履歴も残っていますので無意味ですが.
mit0223

2020/05/13 11:23

「select関数によるI/Oの多重化」というテーマはすばらしいものです。といいますか、このテーマがわかるだけで、プログラマとして食っていけることを保証します。なぜならこれを理解している人が少ないためにインフラ系のアーキテクチャを設計できる人が少ないという構造になっているからです。ということで、質問にこのタイトルを付けただけで+1しておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問