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

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

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

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

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

Q&A

1回答

2088閲覧

C言語で非同期チャトプログラム

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

コンパイル

コンパイルとは、プログラミング言語のテキストソース(ソースコード)をコンピュータ上で実行可能な形式(オブジェクトコード)に変換することをいいます

非同期処理

非同期処理とは一部のコードを別々のスレッドで実行させる手法です。アプリケーションのパフォーマンスを向上させる目的でこの手法を用います。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

0グッド

0クリップ

投稿2020/06/23 05:29

前提・実現したいこと

C言語で非同期のチャットプログラムを作りたいのです。
コンパイルできたのですが実行できません。原因と解決方法を知りたいです。

該当のソースコード

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #define BUFSIZE 256 #define SOCK_MAX 4 #define UNUSED (-1) void chop(char* str) { char* p = strchr(str, '\n'); if (p != NULL) *p = '\0'; } int main(int argc, char *argv[]) { int sockets[6]; // socketの配列,自分用,クライアント用,拒否用 fd_set readfds; struct sockaddr_in server; // サーバプロセスのソケットアドレス情報 struct sockaddr_in client; // クライアントプロセスのソケットアドレス情報 socklen_t fromlen; // クライアントプロセスのソケットアドレス情報の長さ uint16_t port; // ポート番号 char buffer[BUFSIZE]; // メッセージを格納するバッファ int temp = 1; int i, max; int numrcv; if (argc != 2) { fprintf(stderr, "Usage: %s <port>\n", argv[0]); exit(EXIT_FAILURE); } fromlen = sizeof(client); port = atoi(argv[1]); for(i=0;i<6;i++) sockets[i] = UNUSED; sockets[0] = socket(PF_INET, SOCK_STREAM, 0); if (sockets[0] == -1) { perror("server: socket"); exit(EXIT_FAILURE); } // サーバプロセスのソケットアドレス情報の設定 memset((void *) &server, 0, sizeof(server)); // アドレス情報構造体の初期化 server.sin_family = PF_INET; // プロトコルファミリの設定 server.sin_port = htons(port); // ポート番号の設定 server.sin_addr.s_addr = htonl(INADDR_ANY); // ソケットにアドレスをバインド if (bind(sockets[0], (struct sockaddr *) &server, sizeof(server)) == -1) { perror("server: bind"); exit(EXIT_FAILURE); } // 接続要求の受け入れ準備 // バインドされたソケットを待機状態に if (listen(sockets[0], SOCK_MAX + 1) == -1) { perror("server: listen"); exit(EXIT_FAILURE); } max = 1; // クライアントと接続されているソケットへデータ送信 while (1) { // readfds の 初期化 FD_ZERO(&readfds); for(i=0;i<max;i++){ if(sockets[i] != UNUSED) FD_SET(sockets[i], &readfds); } if(select(FD_SETSIZE, &readfds, NULL, NULL, NULL) == -1){ perror("select"); exit(EXIT_FAILURE); } for(i=1;i<max;i++){ if(sockets[i] != UNUSED){ if(FD_ISSET(sockets[i],&readfds)){ // データ受信準備 memset(buffer, '\0', BUFSIZE); // データ送信 recv(sockets[i], buffer, BUFSIZE,0); printf("from client: %s\n", buffer); if (strcmp(buffer, "quit") == 0){ int status = close(sockets[i]); sockets[i] = UNUSED; } printf("received (%d) : %s\n",i,buffer); } } } if(FD_ISSET(sockets[0],&readfds)){ printf("Accept New connection.\n"); for(i = 1;i<max;i++){ if(sockets[i] == UNUSED) break; } sockets[i] = accept(sockets[0], (struct sockaddr *) &client, &fromlen); for (i = 1; i < max; i++) { if (sockets[i] != UNUSED) { if (FD_ISSET(sockets[i], &readfds)) { // データ受信準備 memset(buffer, '\0', BUFSIZE); printf(">: %s\n", buffer); // データ送信 if (fgets(buffer, BUFSIZE, stdin) == NULL) strcpy(buffer, "quit"); chop(buffer); send(sockets[i], buffer, BUFSIZE, 0); if (strcmp(buffer, "quit") == 0) { int status = close(sockets[i]); sockets[i] = UNUSED; } printf("received (%d) : %s\n", i, buffer); } } } if(i<SOCK_MAX +1){ printf("client accepted (%d)\n",i); if(i == max) { max++; }else{ for(;max>0;max--){ if(sockets[max-1] != UNUSED) break; } } }else{ printf("refuse connection.\n"); strcpy(buffer,"Server is too busy.\n"); send(sockets[i],buffer,strlen(buffer),0); close(sockets[i]); } } } return 0; }//サーバー側 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> #include <netinet/in.h> #define BUFSIZE 256 #define SOCK_MAX 4 #define UNUSED (-1) void chop(char* str) { char* p = strchr(str, '\n'); if (p != NULL) *p = '\0'; } int main(int argc, char* argv[]) { int sockets[6]; // socketの配列,自分用,クライアント用,拒否用 fd_set readfds; struct sockaddr_in server; // サーバプロセスのソケットアドレス情報 struct sockaddr_in client; // クライアントプロセスのソケットアドレス情報 socklen_t fromlen; // クライアントプロセスのソケットアドレス情報の長さ uint16_t port; // ポート番号 char buffer[BUFSIZE]; // メッセージを格納するバッファ int temp = 1; int i, max; int numrcv; if (argc != 3) { fprintf(stderr, "Usage: %s <port>\n", argv[0]); exit(EXIT_FAILURE); } fromlen = sizeof(server); port = atoi(argv[1]); for (i = 0; i < 6; i++) sockets[i] = UNUSED; sockets[0] = socket(PF_INET, SOCK_STREAM, 0); if (sockets[0] == -1) { perror("server: socket"); exit(EXIT_FAILURE); } // サーバプロセスのソケットアドレス情報の設定 memset((void*)&client, 0, sizeof(client)); // アドレス情報構造体の初期化 server.sin_family = PF_INET; // プロトコルファミリの設定 server.sin_port = htons(port); // ポート番号の設定 server.sin_addr.s_addr = htonl(INADDR_ANY); // ソケットにアドレスをバインド if (bind(sockets[0], (struct sockaddr*) & server, sizeof(server)) == -1) { perror("server: bind"); exit(EXIT_FAILURE); } // 接続要求の受け入れ準備 // バインドされたソケットを待機状態に if (listen(sockets[0], SOCK_MAX + 1) == -1) { perror("server: listen"); exit(EXIT_FAILURE); } max = 1; // クライアントと接続されているソケットへデータ送信 while (1) { // readfds の 初期化 FD_ZERO(&readfds); for (i = 0; i < max; i++) { if (sockets[i] != UNUSED) FD_SET(sockets[i], &readfds); } if (select(FD_SETSIZE, &readfds, NULL, NULL, NULL) == -1) { perror("select"); exit(EXIT_FAILURE); } for (i = 1; i < max; i++) { if (sockets[i] != UNUSED) { if (FD_ISSET(sockets[i], &readfds)) { // データ受信準備 memset(buffer, '\0', BUFSIZE); printf(">: %s\n", buffer); // データ送信 if (fgets(buffer, BUFSIZE, stdin) == NULL) strcpy(buffer, "quit"); chop(buffer); send(sockets[i], buffer, BUFSIZE, 0); if (strcmp(buffer, "quit") == 0) { int status = close(sockets[i]); sockets[i] = UNUSED; } printf("received (%d) : %s\n", i, buffer); } } } if (FD_ISSET(sockets[0], &readfds)) { printf("Accept New connection.\n"); for (i = 1; i < max; i++) { if (sockets[i] == UNUSED) break; } sockets[i] = accept(sockets[0], (struct sockaddr*) & server, &fromlen); for (i = 1; i < max; i++) { if (sockets[i] != UNUSED) { if (FD_ISSET(sockets[i], &readfds)) { // データ受信準備 memset(buffer, '\0', BUFSIZE); recv(sockets[i], buffer, BUFSIZE, 0); // データ送信 if (strcmp(buffer, "quit") == 0) { int status = close(sockets[i]); sockets[i] = UNUSED; } printf("received (%d) : %s\n", i, buffer); } } } if (i < SOCK_MAX + 1) { printf("client accepted (%d)\n", i); if (i == max) { max++; } else { for (; max > 0; max--) { if (sockets[max - 1] != UNUSED) break; } } } else { printf("refuse connection.\n"); strcpy(buffer, "Server is too busy.\n"); send(sockets[i], buffer, strlen(buffer), 0); close(sockets[i]); } } } return 0; }//クライアント側

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

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

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

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

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

episteme

2020/06/23 05:33

>コンパイルできたのですが実行できません。 どうなるのですか? 現象/症状くらいちゃんと述べなさい。
退会済みユーザー

退会済みユーザー

2020/06/23 06:08

説明不足ですいません。文字を打ち込んでも反応がなく受信送信ができていない状態です。
dodox86

2020/06/23 06:34

どこで停まっているか、なぜ停まっているか、どう直したら良いのか、丸投げ相当です。回答いただいているようにまずご自分でデバッグしましょう。
退会済みユーザー

退会済みユーザー

2020/06/23 06:43

すみませんでした。
guest

回答1

0

まずはデバッグできる環境を揃えましょう
Eclipseや、WindowsならVisualStudioなど。
コードの任意の行で実行を止め、変数の中身を参照できます。
また、そこから1行づつ実行させてコードの流れや変数の変化を見ることができます

そうすれば、アテずっぽでコードを書かなくて済むようになり、
なぜ動かないか他人に聞くようなこともしないで済むようになります

投稿2020/06/23 05:34

y_waiwai

総合スコア88042

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問