3

以下の私のコードでは、send(23 バイト) を実行してから、(select 呼び出しからの戻りに従って) データの準備ができたらいつでも recv を実行する無限の while ループを実行しています。問題は、recv() から常に 1 バイトの読み取りを取得しているように見えることです。TCP はストリーム指向であり、返されるサイズの保証がないことを理解していますが、以下で無効にしたコードを有効にすると (つまり、while ループで recv を無限に実行します)、常に29バイトを読み取ります(私が期待するもの)。ただし、select 関数呼び出しを使用すると、recv は反復ごとに 1 バイトしか読み取りません。これを永遠に続けます (おそらく、すべてのデータの読み取りが終了したとき)。

 int rc = 0, numBytes=0 ; 
 char reply[256] ; 

 // Send a ping
 char PingPacket[23] ; 

 PreparePingPacket(PingPacket) ; 
 numBytes = send(m_sockfd,PingPacket,23,0); 

/*----- COMMENTED OUT
while(1){
  rc = recv(m_sockfd, reply, 256, 0) ;
  if(rc == -1)
  {
    fprintf(stderr, "Error on Sending Ping .. \n") ;   
    return ; 
  }else{
    ParsePacket(reply, rc) ; 
  }
}
*/ END OF COMMENTED PART

// Now wait for all types of pongs to come back
fd_set rfs ; 
while(1)
{
  memset(reply,'\0',256) ; 

FD_ZERO(&rfs) ;

FD_SET(m_sockfd,&rfs) ; 

// Wait for ever .. 
if((rc = select(m_sockfd+1, &rfs, NULL, NULL, NULL)) < 0)
{
  fprintf(stderr, "Select Error after connection .. \n") ; 
  close(m_sockfd) ; 
  return ;
}

if(FD_ISSET(m_sockfd, &rfs))
{
  cout << "Read. for reading" << endl ; 
  int rc = 0 ; 
  if((rc = recv(m_sockfd, reply, sizeof(reply), 0)) == -1)
  {
    cout << "Could not read anything .... " << endl ;   
    fprintf(stderr,"Error: %d\n",errno) ; 
    return ; 
  }
  else if(rc == 0)
  {
    cout << "The other side closed the connection. \n" << endl ; 
  }

}

.....

なぜこれが起こっているのかについてのアイデアはありますか?

4

2 に答える 2