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

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

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

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

Q&A

4回答

7047閲覧

c言語でサーバとプログラム間でのプログラムを作成したいのです。

monamona154

総合スコア13

C

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

0グッド

1クリップ

投稿2016/06/30 10:49

編集2022/01/12 10:55

c言語でサーバとプログラム間でのプログラムを作成したいのです。
サーバを起動してクライアントが19の数字をどれかの数字を送信する→サーバが数字を受け取る→その送られた数字の段の九九をクライアントに送信して表示 というのを1つのサーバと2つ以上のクライアントを使用して作成したいです。
1
9の数字を打つと九九を表示する簡単なプログラムは出来るのですが、これをクライアントとサーバ間でやる方法がわかりません。
回答お願いします。

追記 tcpを使用したチャットプログラムを書きました 参考にして修正してもらいたいです

C言語

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <unistd.h> 5#include <netdb.h> 6#include <sys/socket.h> 7#include <arpa/inet.h> 8 9#define PORT 20007 10#define BUF_SIZE 0x1000 11 12 static void server(int port){ 13 struct sockaddr_in sin; 14 fd_set rfds; 15 int ld, sd[5], len, max,x,y; 16 char *buf, str[256]; 17 18 if ((buf = malloc(BUF_SIZE)) == NULL) { 19 perror("malloc"); 20 return; 21 } 22 23for(x=0;x<5;x++) sd[x] = -1; 24 25 if ((ld = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 26 perror("socket"); 27 goto close_and_end; 28 } 29 30 memset(&sin, 0, sizeof(sin)); 31 sin.sin_family = AF_INET; 32 sin.sin_port = htons(port); 33 if (bind(ld, (struct sockaddr*)&sin, sizeof(sin)) < 0) { 34 perror("bind"); 35 goto close_and_end; 36 } 37 if (listen(ld, 3) < 0) { 38 perror("listen"); 39 goto close_and_end; 40 } 41 42 loop: 43 FD_ZERO(&rfds); 44 FD_SET(ld, &rfds); 45 max = ld; 46 47for(x=0;x<5;x++){ 48 if (sd[x] >= 0) { 49 FD_SET(sd[x], &rfds); 50 if (max < sd[x]) max = sd[x]; 51 } 52 } 53 54 select(max + 1, &rfds, NULL, NULL, NULL); 55 56for(x=0;x<5;x++){ 57 if (sd[x] > 0 && FD_ISSET(sd[x], &rfds)) { 58 if ((len = read(sd[x], buf, BUF_SIZE)) > 0) { 59 if (write(sd[x], buf, len) < 0) { 60 close(sd[x]); 61 sd[x] = -1; 62 } 63for(y=0;y<5;y++){ 64 if(x!=y){ 65 if (sd[y] > 0) { 66 if (write(sd[y], buf, len) < 0) { 67 close(sd[y]); 68 sd[y] = -1; 69 } 70 } 71 } 72 } 73 } 74 else { 75 if (len < 0) perror("read"); 76 close(sd[x]); 77 sd[x] = -1; 78 } 79 } 80 } 81 82 if (FD_ISSET(ld, &rfds)) { 83 int tmpd; 84 85 len = sizeof(sin); 86 if ((tmpd = accept(ld, (struct sockaddr*)&sin, (socklen_t*)&len)) 87 < 0) { 88 perror("accept"); 89 goto close_and_end; 90 } 91 inet_ntop(AF_INET, &sin.sin_addr.s_addr, str, sizeof (str)); 92 printf("connected from %s\n", str); 93 94 if(sd[0]<0) 95 sd[0]=tmpd; 96 else if(sd[1]<0) 97 sd[1]=tmpd; 98 else if(sd[2]<0) 99 sd[2]=tmpd; 100 else if(sd[3]<0) 101 sd[3]=tmpd; 102 else if(sd[4]<0) 103 sd[4]=tmpd; 104 else if(sd[5]<0) 105 sd[5]=tmpd; 106 else{ 107 strcpy(buf, "Server too busy\n"); 108 send(tmpd, buf, strlen(buf), 0); 109 close(tmpd); 110 } 111 } 112 goto loop; 113 114 close_and_end: 115 for(x=0;x<5;x++){ 116 if (sd[x] >= 0) close(sd[x]); 117 if (ld >= 0) close(ld); 118 } 119 120 free(buf); 121} 122 123 static void client(unsigned int ip, int port){ 124 struct sockaddr_in sin; 125 char *buf; 126 int sd, len, i; 127 fd_set rfds; 128 int max; 129 130 if ((buf = malloc(BUF_SIZE)) == NULL) { 131 perror("malloc"); 132 return; 133 } 134 135 if ((sd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { 136 perror("socket"); 137 goto close_and_end; 138 } 139 memset(&sin, 0, sizeof(sin)); 140 sin.sin_family = AF_INET; 141 sin.sin_port = htons(port); 142 sin.sin_addr.s_addr = htonl(ip); 143 if (connect(sd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { 144 perror("connect"); 145 goto close_and_end; 146 } 147 148loop: 149 FD_ZERO(&rfds); 150 max=1; 151 152 if (0 < sd){ 153 FD_SET(sd, &rfds); 154 if(max<sd) max = sd; 155 } 156 157 FD_SET(0, &rfds); 158 159 select(max + 1, &rfds, NULL, NULL, NULL); 160 161 if(FD_ISSET(0, &rfds)){ 162 if (fgets(buf, BUF_SIZE, stdin) <= 0) 163 goto close_and_end; 164 len = strlen(buf); 165 if (send(sd, buf, len, 0) < 0) { 166 perror("send"); 167 goto close_and_end; 168 } 169 } 170 171 if(FD_ISSET(sd, &rfds)){ 172 len = recv(sd, buf, BUF_SIZE, 0); 173 if (len <= 0) { 174 if (len < 0) perror("send"); 175 goto close_and_end; 176 } 177 for (i = 0; i < len; i++) putchar(buf[i]); 178 } 179 goto loop; 180 181 close_and_end: 182 if (sd >= STDIN_FILENO) close(sd); 183 if (sd >= 0) close(sd); 184 free(buf); 185} 186 187 static void usage(void){ 188 printf("server mode: tcp2 -s\n"); 189 printf("client mode: tcp2 -c\n"); 190 exit(0); 191} 192 193 int main(int argc, char **argv, char **env){ 194 if (argc != 2) usage(); 195 if (argv[1][0] != '-') usage(); 196 switch (argv[1][1]) { 197 case 's': 198 server(PORT); 199 break; 200 case 'c': 201 { 202 struct hostent *ent; 203 204 ent = gethostbyname("localhost"); 205 client(ntohl(*(int*)ent->h_addr_list[0]), PORT); 206 break; 207 } 208 default: 209 usage(); 210 } 211 212 exit(0); 213}

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

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

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

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

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

cateye

2016/06/30 10:59

サーバとクライアントの詳細(OS、開発環境など)を教えてください
Zuishin

2016/06/30 10:59

通信に使うのは TCP/IP ですか?
monamona154

2016/07/01 06:31

tcpのチャットのようなシステムでやりたいです。 OSはlinuxで端末を複数使ってやりたいです。 初心者なもので説明不足ですいません。他にも至らないところがあれば指摘してもらいたいです。
cateye

2016/07/01 09:58

>OSはlinuxで端末を複数使って 環境すべて(サーバやクライアント)がLinuxという認識でいいですか? で、”サーバ(Linux)につながっているクライアント(Linux)からみんなでチャットしたい”という事でしょうか? 
monamona154

2016/07/01 13:28

そうです。 それでクライアントから数字を打つと九九が出てくるようにしたいです。
guest

回答4

0

こんにちは。

Linuxネットワークプログラミングが参考になると思います。
Socketプログラミングは結構たいへんですが、上記サイトの解説はステップを踏んでいるので頑張ってみて下さい。

なお、質問をお見受けする限り、この分野の理解はあまり深くないように見えます。ですので、1つ1つ丁寧に進めることをお勧めします。急がば回れです。

投稿2016/07/01 07:09

Chironian

総合スコア23272

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

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

0

まず1対1で実装してみましょう。その際、複数クライアントに対応する下準備として、送受信部分は別々に設計/実装したほうがいいでしょう。また、複数のクライアントに対応させるには、スレッドなりプロセスを起こす必要があると思うので、スレッド(プロセス)間でのデータの受け渡し方法等を考えたうえで、いつでも切り離せるようにしておきましょう。
「加筆」
通信そのものを確立するのも大事ですが・・・”切り離せるように”というのは以下のようなことに対応しやすいようにという事です。
・受信部は一か所で着信があったら、そのクライアント用のスレッドを起こす。(これも、データを受信して結果を送信するだけなのか、それともクライアントが切断するまでなのか?)
・応答部は送信するデータがあったらクライアントに送信する。(A,B,Cと3人のユーザがいる場合Aさんが入力したデータを受信したサーバはすべてのクライアント(B,C)に送るのか?・・・この方が楽w)
・送受信の排他制御はどうするか? (送受信ともキュー管理が必要と思われるので、キューの読み書き時に排他制御が必要です。・・・チャット・クライアントであれば、ユーザが入力中にデータを受信したらどうするか?)
とか、いろいろ考えることがありますね?・・・他の方も書かれていますが、1対多の通信の場合スレッド同士の排他制御がどうしても必要になります。とりあえず思いついたことなので話がごちゃ混ぜになってしまいますが・・・
送信データが発生したら送信キューに入れる。送信スレッド(?)は送信キューにデータがあったらそれを送信する。
受信部はデータを受信したら受信キューに入れる。受信データの処理をするスレッドは、受信キューにデータがあったらそれを取り出して処理をする。
・・・というような処理になると思います。

投稿2016/07/02 00:45

編集2016/07/02 13:32
cateye

総合スコア6851

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

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

0

質問者さんの知識・技術で言えば、作ろうとしているもののハードルが高すぎると思います。
まず HTTP クライアントを作りましょう。特定のサイトからページソースを取ってくるのが目標です。
それができたら HTTP サーバーを作りましょう。
もちろん、ポート 80 やポート 8080 は競合すると思うので、別のポートを使ってください。
先ほど作ったクライアントで動作確認できるはずです。
そこまで行けば、目標のソフトの 9 割方は出来たも同然だと思います。
###追記
単純な 1 対 1 のクライアント・サーバーで、サーバーの役目は九九の答えを返すだけだと思っていたので、9 割型と書きましたが、多対一でチャット機能が付くとなると話は別です。スレッドセーフなコーディングも勉強しなくてはなりません。これも結構厄介なカテゴリですが、頑張ってください。

投稿2016/07/01 06:59

編集2016/07/02 01:00
Zuishin

総合スコア28656

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

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

0

クライアントとサーバって、

ウェブを介しての方?
それとも、ただ単に2つのソフト間でデータの受け取りをしたいってこと?

あと、OS はなんでしょうか。

OS依存を無くしたやり方もあるかもしれませんが、
Windows API を使う方もあるので。

Windows なら EternlWindows の"ネットワーク" の "WinSock"とか、COMを使う方とか。

投稿2016/06/30 11:04

BeatStar

総合スコア4958

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問