私は、クライアントとサーバーがお互いの順番を待たずにチャットすることになっている、非同期/ノンブロッキング udp クライアント サーバー アプリケーションを作成したいと考えていました。これは select() でできることを知りました...
これが私のサーバーです(通信部分のみに言及):
fd_set readfds,writefds;
while(1){
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(sd,&readfds);
FD_SET(sd,&writefds);
int rv = select(n, &readfds, NULL, NULL, NULL);
if(rv==-1)
{
printf("Error in Select!!!\n");
exit(0);
}
if(rv==0)
{
printf("Timeout occurred\n");
}
if (FD_ISSET(sd, &readfds))
{
int client_length = (int)sizeof(struct sockaddr_in);
memset(&buffer,0,sizeof(buffer));
int bytes_received = recvfrom(sd, buffer,SIZE, 0, (struct sockaddr *)&client, &client_length);
if (bytes_received < 0) {
fprintf(stderr, "Could not receive datagram.\n");
closesocket(sd);
WSACleanup();
exit(0);
}
}
printf("\nClient says: %s",buffer);
printf("\nWrite :");
fgets(buffer,SIZE,stdin);
if(FD_ISSET(sd,&writefds)) {
int client_length = (int)sizeof(struct sockaddr_in);
if(sendto(sd, buffer,strlen(buffer), 0, (struct sockaddr *) &client,client_length)<0) {
printf("Error sending the file! \n");
printf("%d\n",WSAGetLastError());
exit(1);
}
}
}
closesocket(sd);
WSACleanup();
return 0;
}
これは私のクライアントです:
fd_set readfds,writefds;
while(1)
{
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(cs,&readfds);
FD_SET(cs,&writefds);
int rv=select(n,&readfds,&writefds,NULL,NULL);
if(rv==-1)
{
printf("Error in Select!!!\n");
exit(0);
}
if(rv==0)
{
printf("Timeout occurred\n");
}
printf("\nWrite ");
fgets(send_buffer,SIZE,stdin);
if(FD_ISSET(cs,&writefds))
{
int server_length = sizeof(struct sockaddr_in);
FD_CLR(cs,&writefds);
if (sendto(cs, send_buffer, (int)strlen(send_buffer) + 1, 0, (struct sockaddr *)&server, server_length) == -1)
{
fprintf(stderr, "Error transmitting data.\n");
closesocket(cs);
WSACleanup();
exit(0);
}
}
char file_buffer[SIZE];
//Reply reception from the server:"Ready to receive file"
int data2=0;
if (FD_ISSET(cs, &readfds))
{
FD_CLR(cs,&readfds);
int server_length = sizeof(struct sockaddr_in);
data2=recvfrom(cs,file_buffer,strlen(file_buffer)-1,0,(struct sockaddr *)&server,&server_length);
//file_buffer[data2]='\0';
if(data2<0)
{
printf("Server is not on:(\n");
exit(0);
}
}
//printf("%d",data2);
printf("\nServer says:");
for(int i=0;i<data2;i++)
{
putchar(file_buffer[i]);
}
}
return 0;
}
最初にサーバー側で次のように書きました。int rv = select(n, &readfds, &writefds, NULL, NULL);
しかし、サーバーとクライアント間の通信が適切ではないという事実に加えて、サーバーが初期化されたときに、サーバーコンソールに空の配列全体が出力されました。「&writefds」を削除すると、冗長データは削除されましたが、不適切な通信の問題は引き続き発生します...誰かが私を助けてくれたら本当にありがたいです...