주요 콘텐츠로 건너뛰기

다음 STCP 코드 조각은 내가 관찰한 문제를 보여 줍니다.  읽을 데이터가 있을 때까지 recv 호출을 차단한 다음 수신된 데이터를 처리하고 recv를 다시 호출하여 더 많은 데이터(또는 오류)로 반환하거나 차단합니다.  오류가 발생하면 recv가 -1을 반환하고 오류 코드가 오류 변수에서 설정됩니다.  코드가 확인된 것처럼 보이나요?

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes == -1)
      {
      perror ("Unexpected error at recv");
      exit (errno);
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

코드는 원격 피어가 연결을 우아하게 닫히지 않을 것이라고 가정합니다.  원격 피어가 우아하게 닫히면 닫거나 종료 함수를 호출하는 경우 recv는 0바이트를 반환하여 로컬 응용 프로그램에 이를 나타냅니다.  이력서에 대한 후속 호출은 0 바이트를 반환계속됩니다.  그 결과 코드가 이제 아무 것도 하지 않는 타이트한 루프에 있습니다.  예를 들어

수신된 바이트 수 : 8
수신된 바이트 수 : 57
수신된 바이트 수 : 16
수신된 바이트 수 : 1
수신된 바이트 수 : 1
수신된 바이트 수 : 0
수신된 바이트 수 : 0
수신된 바이트 수 : 0
수신된 바이트 수 : 0
수신된 바이트 수 : 0
. . . . .

응용 프로그램 프로토콜이 원격 피어가 연결을 우아하게 닫히지 않도록 지시하더라도 연결이 정상적으로 닫히지 않도록 보장할 수 없습니다.  원격 응용 프로그램에 버그가 있거나 원격 TCP 스택이 응용 프로그램 프로세스가 종료될 때 우아할 수 있는 닫을 수 있습니다.  또는 다른 응용 프로그램이 연결을 만든 다음 예상 응답을 얻지 못했을 때 닫을 수 있습니다.  포트 스캔 또는 배너 잡기를 수행하는 보안 감사(또는 악의적인 사용자)도 우아한 닫을 수 있습니다.  결론은 항상 0 바이트의 경우를 처리해야한다는 것입니다.

while (1)
   {
   cBytes = recv (socks1, buffer, BUFFERLEN, 0);
   if (cBytes <= 0)
      {
      if (cBytes < 0)
         {
         perror ("Unexpected error at recv");
         exit (errno);
         }
      else
         {
         printf ("received closen");
         close (socks1);
         exit (0);
         }
      }
   else
      printf ("number of bytes received : %dn", cBytes);
   }

수신된 바이트 수 : 28
수신된 바이트 수 : 2
수신된 바이트 수 : 58
마감

 

© 2024 스트라투스 테크놀로지스.