クライアントとサーバーの2つのプログラムを作成しようとしています。クライアントはソケット接続を開き、接続を受け入れると新しいスレッドが生成された後、デタッチして残りの読み取り/書きます。問題は、複数の書き込みを行い、クライアントからの読み取りで正しいデータが得られないが、サーバー側では正しいデータが送信されたことが印刷されるということです。スレッドを使用してソケットから複数の読み込み/書き込みを処理するには?
これは、私のコードが新しいスレッドを生成するように見えるもので、それらのスレッドをどのように処理するかです。
while(1){
listen(sockfd,5);
// determine the size of a clientAddressInfo struct
clilen = sizeof(clientAddressInfo);
int *newsockfd = malloc(sizeof(int));
// block until a client connects, when it does, create a client socket
*newsockfd = accept(sockfd, (struct sockaddr *) &clientAddressInfo, &clilen);
// if the connection blew up for some reason, complain and exit
if (*newsockfd < 0){
error("ERROR on accept");
}
connection_args *args = malloc(sizeof(connection_args));
args->file_descrp = newsockfd;
pthread_t tid;
pthread_create(&tid,NULL, handle_connect, args);
}
void * handle_connect(void* args){
connection_args* connect_arg = (connection_args*)args;
pthread_detach(pthread_self());
int n = -1;
char buffer[256];
bzero(buffer,256);
//while not close;
while(1){
// try to read from the client socket
n = read(*connect_arg->file_descrp,buffer,255);
printf("input: %s\n", buffer);
// if the read from the client blew up, complain and exit
if (n < 0){
error("ERROR reading from socket");
}
int fd;
if(strcmp("open",buffer) == 0){
fd = open("file.txt",0);
bzero(buffer,256);
sprintf(buffer,"%d",fd);
}else if(strcmp("read",buffer) == 0){
char *read_buffer = malloc(sizeof(char)*256);
bzero(read_buffer,256);
fd = read(get_filedescrp(),read_buffer,30);
bzero(buffer,256);
sprintf(buffer,"%s,%d",read_buffer,fd);
}else if(strcmp("close",buffer) == 0){
break;
}
printf("buffer_send: %s\n",buffer);
// try to write to the client socket
n = write(*connect_arg->file_descrp,buffer,sizeof(buffer));
// if the write to the client below up, complain and exit
if (n < 0){
printf("here!!\n");
error("ERROR writing to socket");
}
bzero(buffer,256);
}
printf("Left thread\n");
return NULL;
}
ちょうど一般的にWiresharkと[Netcat](https://linux.die.net/man/1/nc)を使ってネットワークコードをデバッグすることをお勧めします。 Wiresharkはあなたが送信しているものを見せるようにします。また、既知のサーバとクライアントとして 'nc'を使用することで、サーバとクライアントを分離して、一度に取り込む変数の数を減らすことができます。 – yano
'accept()'ループの中で 'listen()'を呼び出さないでください。それを1回呼び出してから、ループに入ります。そして、あなたのソケット記述子を 'malloc()'する必要はありません。そして、 'printf()'や 'strcmp()'のように、ヌル終了した操作を実行する前に 'buffer'をヌル文字で終わらせるわけではありません。また、TCPがストリーミング転送であることを考慮していないので、 'read()'が完全な文字列を受け取るという保証はなく、時には部分的なデータを受け取ることができます。送信側でコマンドを区切り、読み込み側で区切り文字を探す必要があります。 –
クライアント側でread()を2回呼び出すと、正しいデータが得られます。私はTCPがストリーミングトランスポートであるという事実をどのように説明しますか?ヌル以外の応答が得られるまでread()を呼び出し続けますか?ヌル終了文字についても、ヌル終了文字で文字列を送ると、読み込んだ後に手動で再追加する必要がありますか? – user1457388