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

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

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

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

Q&A

1回答

1049閲覧

ローカルホスト間での計算機通信をしたい(Linax)

raiboz1115

総合スコア4

C

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

0グッド

0クリップ

投稿2021/07/26 15:45

C言語でLinax上で計算機間のチャット幼なものを作りたいです。一度だけ送信できるコードをwhile文で回して一方的に送り続けるものは作れたのですが、交互に送りあうチャットのようなものを作ろうとした際、1回目に受け取った側が初めて送るときのconnect関数でエラーが出ます。(Connection refused)以下がそのコードです。解決方法が知りたいです。

C言語

1//server(初めに受け取る方) 2#include <stdio.h> 3#include <stdlib.h> 4#include <sys/types.h> 5#include <sys/socket.h> 6#include <netdb.h> 7#include <unistd.h> 8#include <strings.h> 9 10#define SERVICE_PORT 3500 11#define SERVICE_PORT1 2999 12#define BUF_LEN 1024 13 14int main(int argc, char **argv) { 15 struct hostent *host; 16 struct sockaddr_in okuserver,ukeserver, client; 17 int soc, soc1,soc2,string_length, oku_data_length; 18 socklen_t uke_data_size; 19 char buf[BUF_LEN]; 20 int f = 1; 21 22 host = gethostbyname("localhost"); 23 24 while(1){ 25 bzero((char *)&ukeserver, sizeof(ukeserver));//client->server(recv) 26 ukeserver.sin_family=AF_INET; 27 ukeserver.sin_port=htons(SERVICE_PORT); 28 ukeserver.sin_addr.s_addr = INADDR_ANY; 29 soc1=socket(AF_INET,SOCK_STREAM,0); 30 if(bind(soc1,(struct sockaddr *)&ukeserver,sizeof(ukeserver))==-1){ 31 perror("bind"); exit(-1); } 32 if(listen(soc1,5)==-1){ 33 perror("listen"); exit(-1); } 34 uke_data_size=sizeof(client); 35 if(f == 1){ 36 printf("Waiting for connection request.\n"); 37 f = 0; 38 } 39 40 if((soc2=accept(soc1,(struct sockaddr *)&client,&uke_data_size))<0){ 41 perror("accept"); exit(-1); } 42 string_length=read(soc2,buf,BUF_LEN); 43 write(1,"From client:",12); 44 write(1,buf,string_length); 45 write(soc2,buf,string_length); 46 if(string_length == 1){ 47 break; 48 } 49 close(soc2); close(soc1);//recv end 50 51 bzero((char *)&okuserver, sizeof(okuserver));//server->client(send) 52 okuserver.sin_family=AF_INET; 53 okuserver.sin_port=htons(SERVICE_PORT1); 54 bcopy((char *)host->h_addr,(char *)&okuserver.sin_addr,host->h_length); 55 oku_data_length=sizeof(okuserver); 56 soc=socket(AF_INET,SOCK_STREAM,0); 57 58 printf("1\n"); 59 if(connect(soc,(struct sockaddr *)&okuserver,oku_data_length)<0){ 60 perror("connect"); 61 exit(-1); 62 } 63 printf("2\n"); 64 bzero(buf,BUF_LEN); 65 printf("server:"); 66 fflush(stdout); 67 string_length=read(0,buf,BUF_LEN); 68 write(soc,buf,string_length); 69 string_length=read(soc,buf,BUF_LEN); 70 if(string_length == 1){ 71 break; 72 } 73 close(soc);//send end 74 75 76 } 77 return(0); 78} 79 80 81 82//client(初めに送る方) 83#include <stdio.h> 84#include <stdlib.h> 85#include <sys/types.h> 86#include <sys/socket.h> 87#include <netdb.h> 88#include <unistd.h> 89#include <strings.h> 90 91 92#define SERVICE_PORT 3500 93#define SERVICE_PORT1 2999 94#define BUF_LEN 1024 95 96int main(int argc,char **argv) 97{ 98 struct hostent *host; 99 struct sockaddr_in okuserver,ukeserver, client; 100 int soc,soc1, soc2, oku_data_length,string_length; 101 socklen_t uke_data_size; 102 char buf[BUF_LEN]; 103 104 if(argc<2) { 105 printf("Usage: %s server_name\n",argv[0]); 106 exit(-1); 107 } 108 if((host=gethostbyname(argv[1]))==NULL){ 109 perror("gethostbyname"); 110 exit(-1); 111 } 112 while(1){ 113 bzero((char *)&okuserver, sizeof(okuserver));//client->server(send) 114 okuserver.sin_family=AF_INET; 115 okuserver.sin_port=htons(SERVICE_PORT); 116 bcopy((char *)host->h_addr,(char *)&okuserver.sin_addr,host->h_length); 117 oku_data_length=sizeof(okuserver); 118 119 soc=socket(AF_INET,SOCK_STREAM,0); 120 121 122 123 if(connect(soc,(struct sockaddr *)&okuserver,oku_data_length)<0){//一度目のここでエラーが出る 124 perror("connect"); 125 exit(-1); 126 } 127 128 129 130 bzero(buf,BUF_LEN); 131 printf("client:"); 132 fflush(stdout); 133 string_length=read(0,buf,BUF_LEN); 134 write(soc,buf,string_length); 135 string_length=read(soc,buf,BUF_LEN); 136 if(string_length == 1){ 137 break; 138 } 139 close(soc);//send end 140 141 bzero((char *)&ukeserver, sizeof(ukeserver));//server->client(recv) 142 ukeserver.sin_family=AF_INET;// 143 ukeserver.sin_port=htons(SERVICE_PORT1); 144 ukeserver.sin_addr.s_addr = INADDR_ANY; 145 soc1=socket(AF_INET,SOCK_STREAM,0); 146 if(bind(soc1,(struct sockaddr *)&ukeserver,sizeof(ukeserver))==-1){ 147 perror("bind"); exit(-1); } 148 if(listen(soc1,5)==-1){ 149 perror("listen"); exit(-1); } 150 uke_data_size=sizeof(client); 151 152 if((soc2=accept(soc1,(struct sockaddr *)&client,&uke_data_size))<0){ 153 perror("accept"); exit(-1); } 154 string_length=read(soc2,buf,BUF_LEN); 155 write(1,"From server:",12); 156 write(1,buf,string_length); 157 write(soc2,buf,string_length); 158 if(string_length == 1){ 159 break; 160 } 161 close(soc2); close(soc1);//recv end 162 163 164 165 166 } 167 return(0); 168} 169 170

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

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

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

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

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

y_waiwai

2021/07/26 22:05

エラーが出たなら、エラーメッセージを提示しましょう エラーメッセージは、いらぬ翻訳省略しないで、出たそのママをコピペで提示してください
dodox86

2021/07/27 00:11

どちらもクライアントでありサーバーにもなる(ことを目指している?)ようなコードですが、一般的にはこうは造らないですし、かなり無理・無茶しているかんじがします。C言語でのTCPの一般的なクライアント、サーバーのプログラムを学んでからの方が良いのでは。
raiboz1115

2021/07/27 05:25

エラーメッセージは、質問文にも書いてある通り、Connection refusedのみです。perrorで出力されているものだと思います。 dodox86さん、意図をくみ取ってくださり、ありがとうございます。 ごり押ししてるのは承知済みですが、基礎がわからないので動けばいいかなという感じです。 このコードでは数か所かえるだけで起動しませんかね?
jimbe

2021/07/28 19:48

ソケットは双方向の通信路ですので、送受信を 1 つのソケットで出来ます。 それだけでもコードが大分変わるのではないでしょうか。
thkana

2021/07/28 23:32

一応(かどうか)ここはITエンジニア特化型のQ&Aサイトということなので... > 基礎がわからないので動けばいいかな これはエンジニア的には禁じ手ですね。絶体絶命でそういうケースが起こってしまうのはともかく、単に基礎を調べるのが面倒だから、で持ち出してよい手段ではないと思います。 で。 なぜそのようなものを作りたいのですか? なにかの学習・練習であるなら、基礎を無視したものを作ってもメリットがないでしょうし、 何らかの実用に供したいなら、Cで苦労していないで他の(ソケットがきれいにラップされた)言語で作ったほうがよいと思いますが。
guest

回答1

0

折角ご提示頂いているコードですが、動くように思われませんでしたので、コピペの材料のみとさせて頂いて以下のコードを構成してみました。
パラメータ無しでサーバモード(受信先行)、ホスト名を指定するとクライアントモード(送信先行) です。
慣れない windows/cygwin 環境で作りましたで NULL の定義が有ったりしますが、そこは無視でお願いします。

参考になれば・・・と思いましたが、「基礎がわからないので」と明言されますと難しいかもしれませんね・・・。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <sys/types.h> 4#include <sys/socket.h> 5#include <netdb.h> 6#include <unistd.h> 7#include <string.h> 8 9#define SERVICE_PORT 3500 10#define BUF_LEN 1024 11#define STDOUT 1 12 13#ifndef NULL 14#define NULL (void*)0 15#endif 16 17int clientConnection(char *serverName) { 18 struct hostent *host; 19 if ((host = gethostbyname(serverName)) == NULL) { 20 perror("gethostbyname"); 21 exit(-1); 22 } 23 24 int s = socket(AF_INET, SOCK_STREAM, 0); 25 26 struct sockaddr_in server; 27 bzero((char*) &server, sizeof(server)); //client->server(send) 28 server.sin_family = AF_INET; 29 server.sin_port = htons(SERVICE_PORT); 30 bcopy((char*) host->h_addr,(char *)&server.sin_addr,host->h_length); 31 int size = sizeof(server); 32 if (connect(s, (struct sockaddr*) &server, size) < 0) { 33 perror("connect"); 34 exit(-1); 35 } 36 37 return s; 38} 39 40int serverConnection() { 41 42 int ss = socket(AF_INET, SOCK_STREAM, 0); 43 44 struct sockaddr_in server; 45 bzero((char*) &server, sizeof(server)); //client->server(recv) 46 server.sin_family = AF_INET; 47 server.sin_port = htons(SERVICE_PORT); 48 server.sin_addr.s_addr = INADDR_ANY; 49 if (bind(ss, (struct sockaddr*) &server, sizeof(server)) == -1) { 50 perror("bind"); 51 close(ss); 52 exit(-1); 53 } 54 55 if (listen(ss, 5) == -1) { 56 perror("listen"); 57 close(ss); 58 exit(-1); 59 } 60 61 printf("Waiting for connection request.\n"); 62 int s; 63 struct sockaddr_in client; 64 int size = sizeof(client); 65 if ((s = accept(ss, (struct sockaddr*) &client, &size)) < 0) { 66 perror("accept"); 67 close(ss); 68 exit(-1); 69 } 70 71 close(ss); 72 return s; 73} 74 75int writemsg(int fd, const char *msg) { 76 return write(fd, msg, strlen(msg)); 77} 78/** 改行までを読み込み(改行は付いたまま) */ 79int readmsg(int fd, char *buf, int size) { 80 int index = 0; 81 do { 82 if(index >= size-1) return 0; //overflow 83 int n = read(fd, &buf[index], size-index-1); 84 if(n < 0) { 85 perror("read"); 86 return 0; 87 } 88 index += n; 89 } while(buf[index-1] != '\n'); 90 buf[index] = '\0'; 91 return index; 92} 93 94const char* prestr[] = { "client:", "server:" }; 95 96int main(int argc, char **argv) { 97 //パラメータ解析 98 opterr = 0; //getoptエラー表示 抑制 99 int opt, help=0; 100 while ((opt = getopt(argc, argv, "h")) != -1) { 101 switch (opt) { 102 case 'h': 103 default: 104 help = !0; 105 } 106 } 107 char *hostname = (optind < argc ? argv[optind++] : NULL); 108 if(help || optind < argc) { 109 printf("Usage: %s [-h] [server_name]\n", argv[0]); 110 exit(-1); 111 } 112 113 int s = (hostname == NULL ? serverConnection() : clientConnection(hostname)); 114 int initMode = (hostname == NULL ? 1 : 0); //1=サーバ:受信, 0=クライアント:送信 115 116 char buf[BUF_LEN]; 117 //mode を切り替えることで送信/受信を交互に繰り返す 118 for (int mode=initMode; ; mode ^= 1) { 119 if(mode) { 120 //受信 121 if(readmsg(s, buf, BUF_LEN) == 0) break; 122 writemsg(STDOUT, prestr[initMode^1]); 123 writemsg(STDOUT, buf); 124 } else { 125 //送信 126 writemsg(STDOUT, prestr[initMode]); 127 if(fgets(buf, BUF_LEN, stdin) == NULL) break; 128 writemsg(s, buf); 129 } 130 } 131 132 close(s); //recv end 133 134 return (0); 135}

投稿2021/07/29 08:18

編集2021/07/29 08:26
jimbe

総合スコア12648

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問