3

Select 呼び出しでクライアント サーバー コードを試しています。しかし、クライアントからサーバーに送信すると、クライアントがIstパケットの後に何も送信していなくても、サーバーはクライアントから送信されたバッファから継続的に読み取ります.どこが間違っていますか?

以下はコードのスニペットです。

fd_set readSet,master_list_read;
FD_ZERO(&master_list_read);
FD_SET(STDIN, &master_list_read);//stdin manually trigger reading
FD_SET(sockfd, &master_list_read);//tcp socket

struct timeval tv;
int retval;
tv.tv_sec = 10;
tv.tv_usec = 0;
while(1)
{ 
bool idle=false;
char *buffer=NULL;
int n;

tv.tv_sec = 10;
readSet=master_list_read;
retval = select(sockfd+1, &readSet, NULL, NULL,&tv);
if (retval == -1) 
{
    perror("Error in select\n");
    exit(4);
}
else if(retval==0)
{ 
    printf("*********SEND SUCCESSFUL******\n");
}       
else 
{   
if(FD_ISSET(0, &readSet))
{
    bzero(buf,256);
    fgets(buf,256,stdin); 
    if (send(sockfd, buffer,n, 0) == -1) perror("error in sending MSG to server\n");
}

else  if (FD_ISSET(sockfd, &readSet))  // receives data from server,print it on StdOutput
{  
    bzero(buf,256);
    int nbytes = recv(sockfd, buf, 256,0);
    if(nbytes<=0)
    {
        perror("recv error from server \n");
        exit(0);
    }
}

} //END OF ELSE 
} //end of while
close(sockfd);          
return 0;
4

1 に答える 1

6

ループ内のselect()呼び出しは変更されません。これは、後で FD_ISSET() チェックが成功することを意味します。while(1)readSet

解決策は簡単です。反復ごとに fd_set をクリアします。

FD_ZERO(&master_list_read);
FD_SET(STDIN, &master_list_read);
FD_SET(sockfd, &master_list_read);
// only now the select() returns what you need
retval = select(sockfd+1, &master_list_read, NULL, NULL,&tv);

// use the master_list_read later

fd_set をコピーするだけでは問題は解決しません。

于 2012-09-17T22:44:53.433 に答える