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
エラーが出たなら、エラーメッセージを提示しましょう
エラーメッセージは、いらぬ翻訳省略しないで、出たそのママをコピペで提示してください
どちらもクライアントでありサーバーにもなる(ことを目指している?)ようなコードですが、一般的にはこうは造らないですし、かなり無理・無茶しているかんじがします。C言語でのTCPの一般的なクライアント、サーバーのプログラムを学んでからの方が良いのでは。
エラーメッセージは、質問文にも書いてある通り、Connection refusedのみです。perrorで出力されているものだと思います。
dodox86さん、意図をくみ取ってくださり、ありがとうございます。
ごり押ししてるのは承知済みですが、基礎がわからないので動けばいいかなという感じです。
このコードでは数か所かえるだけで起動しませんかね?
ソケットは双方向の通信路ですので、送受信を 1 つのソケットで出来ます。
それだけでもコードが大分変わるのではないでしょうか。
一応(かどうか)ここはITエンジニア特化型のQ&Aサイトということなので...
> 基礎がわからないので動けばいいかな
これはエンジニア的には禁じ手ですね。絶体絶命でそういうケースが起こってしまうのはともかく、単に基礎を調べるのが面倒だから、で持ち出してよい手段ではないと思います。
で。
なぜそのようなものを作りたいのですか?
なにかの学習・練習であるなら、基礎を無視したものを作ってもメリットがないでしょうし、
何らかの実用に供したいなら、Cで苦労していないで他の(ソケットがきれいにラップされた)言語で作ったほうがよいと思いますが。