C言語でソケットを利用するプログラムを書いていて、クライアントプログラムでファイル名を送信して、サーバプログラムが受け取ったファイル名のファイルを開きその中身を送信するプログラムを作成しました。
クライアントプログラムの実行結果は次のようになり、クライアント、サーバプログラムを動作させ、クライアントでファイル名を送信するとサーバ側でファイルを開きその中身をループして送信してくれるのですがサーバがファイルの中身をすべて送信し終わってもクライアントはwhileループでrecv()で待ち続けているためか次のファイル名の入力ができない状態になっています。そのため次の実行例では^Cで強制終了しています。どのように修正すれば正しいプログラムになるでしょうか。
input filename: test.txt aaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbccccc ddddekekkkkkkkk 000fffff44444fccccc ^C
クライアント側のプログラム
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#include <sys/socket.h> 6#include <sys/types.h> 7#include <arpa/inet.h> 8#include <errno.h> 9#include <unistd.h> 10#include <netdb.h> 11#include <netinet/in.h> 12#include <fcntl.h> 13 14#define PORT 8888 15#define BUFSIZE 128 16 17int main(int argc, char *argv[]){ 18 struct sockaddr_in addr; 19 int fd, n; 20 char buf[BUFSIZE]; 21 22 if((fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ 23 perror("socket"); 24 exit(-1); 25 } 26 27 memset(&addr, 0, sizeof(addr)); 28 addr.sin_family = AF_INET; 29 addr.sin_port = htons(PORT); 30 addr.sin_addr.s_addr = inet_addr("127.0.0.1"); 31 32 if(connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0){ 33 perror("connect"); 34 exit(-1); 35 } 36 37 while(1){ 38 printf("input filename: "); 39 fgets(buf, BUFSIZE, stdin); 40 send(fd, buf, BUFSIZE, 0); 41 while((n = recv(fd, buf, BUFSIZE, 0)) > 0) // ファイルをすべて読み出してもここから抜けられない? 42 write(1, buf, n); 43 } 44 45 close(fd); 46 47 return 0; 48}
サーバ側のプログラム
c
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#include <sys/socket.h> 6#include <sys/types.h> 7#include <arpa/inet.h> 8#include <errno.h> 9#include <unistd.h> 10#include <netdb.h> 11#include <netinet/in.h> 12#include <fcntl.h> 13 14#define PORT 8888 15#define BUFSIZE 128 16 17int main(int argc, char *argv[]){ 18 struct sockaddr_in saddr, caddr; 19 int fd1, fd2, fp, n, ret, len; 20 char buf[BUFSIZE]; 21 char *c; 22 23 if((fd1 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0){ 24 perror("socket"); 25 return -1; 26 } 27 28 memset(&saddr, 0, sizeof(saddr)); 29 saddr.sin_family = AF_INET; 30 saddr.sin_port = htons(PORT); 31 saddr.sin_addr.s_addr =htonl(INADDR_ANY); 32 33 if(bind(fd1, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){ 34 perror("bind"); 35 exit(-1); 36 } 37 38 if(listen(fd1, 5)){ 39 perror("listen"); 40 return -1; 41 } 42 43 if((fd2 = accept(fd1, (struct sockaddr*)&caddr, &len)) < 0){ 44 perror("accept"); 45 return -1; 46 } 47 48 49 while(1){ 50 recv(fd2, buf, BUFSIZE, 0); 51 c = strchr(buf, '\n'); if(c != NULL) *c = '\0'; //remove '\n' 52 printf("filename : [%s]\n", buf); 53 if((fp = open(buf, O_RDONLY, 0644)) < 0){ 54 perror("open"); 55 exit(-1); 56 } 57 while((n = read(fp, buf, sizeof(buf)))) 58 send(fd2, buf, n, 0); 59 } 60 61 close(fd1); close(fd2); 62 63 return 0; 64}
![guest](/img/icon/icnUserSample.jpg)
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。