2014-07-07 2 views
0

IRC 봇 (아직)을 쓰고 있으며 몇 달 동안 여기 저기에 난처 해했습니다. 데이터를 받아서 인쇄하는 간단한 함수입니다. 항상 작동하지는 않습니다. 예를 들어, 봇이 서버에 연결하면 서버가 MoTD를 보내고 여기서이 함수가 인쇄를 시도 할 때 맨 끝에 보통 두 줄이 잘립니다. 여기 소켓에서 들어오는대로 터미널로 데이터를 인쇄하는 방법

int mainLoop(int socketDescriptor) 
{ 
    int bytesReceived = 0, i; 
    char workingBuffer[RECVBUFF]; 

    do 
    { 
     for (i = 0; i < RECVBUFF; i += bytesReceived) 
     { 
      bytesReceived = recv(
        socketDescriptor, 
        workingBuffer + i, 
        RECVBUFF - i, 
        0); 
     } 

     for (i = 0; i < RECVBUFF; ++i) 
      printf("%c", workingBuffer[i]); 
    } 
    while(1); 

    return 0; 
} 

내 프로그램의 출력 및 irssi 같은 클라이언트의 출력을 보여주는 스크린 샷입니다. 내 프로그램을 볼 수 있듯이

Irssi's output

My program's output 단지 마지막 덩어리에 포장 마차 인쇄를 중지합니다. 어떻게 해결할 수 있습니까?

+2

을 스크린 샷은 텍스트 만 표시합니다. 예쁜 텍스트 대신 원본 텍스트를 게시 할 가능성이 있습니까? 사진? snip 지시자를 사용하여 관리 가능한 3 줄 정도의 MotD를 스니핑합니다. – Deduplicator

+0

터미널 텍스트를 _ 텍스트로 표시하는 것이 그림으로 표시하는 것보다 유용합니다. – chux

답변

0

첫 번째 for 버퍼가 가득차면 루프가 종료되지 않습니다. 응답의 마지막 부분은 버퍼를 정확히 채우지 않을 것입니다. 이 같은 뭔가 도움이 될 수 있습니다 : 또는

for (i = 0; i < RECVBUFF; i += bytesReceived) 
{ 
    bytesReceived = recv(
      socketDescriptor, 
      workingBuffer + i, 
      RECVBUFF - i, 
      0); 

    if (!bytesReceived) 
     break; 
} 

:

bytesReceived = 1; /* so the loop does at least one iteration */ 

for (i = 0; i < RECVBUFF && bytesReceived; i += bytesReceived) 
{ 
    bytesReceived = recv(
      socketDescriptor, 
      workingBuffer + i, 
      RECVBUFF - i, 
      0); 
} 

OK, 새로운 계획 - 간단한 (아마하지 않는 것이 좋습니다) 솔루션 : 그로서

int mainLoop(int socketDescriptor) 
{ 
    int bytesReceived = 0, i; 
    char workingBuffer[RECVBUFF]; 

    do 
    { 
     bytesReceived = recv(
       socketDescriptor, 
       workingBuffer, 
       RECVBUFF, 
       0); 

     for (i = 0; i < bytesReceived; ++i) 
      printf("%c", workingBuffer[i]); 
    } 
    while(bytesReceived); 

    return 0; 
} 
+0

그러나 소켓에서 0 바이트가 대기중인 경우 recv()가 차단되지 않습니까? – Red

+0

예, 가능합니다. 0을 리턴하는 recv()는 피어가 연결을 종료했음을 나타냅니다. –

+0

흠, 네가 맞아, 그다지 좋지 않아. 첫 번째'for' 루프는 그냥 버려야한다고 생각합니다 - 모든'recv()'다음에'printf()'를합니다. 또는,'select()'를 사용하여 보류중인 입력을 검사하십시오. 또는 소켓을 non-blocking으로 설정하십시오 ... –

관련 문제