2011-01-22 4 views
2

소켓에서 데이터를 읽으려는 C 코드를 작성하려고하는데 데이터가 들어오는 길이를 알지 못합니다. 데이터를 제어 할 수 없습니다. 보내는 사람.소켓 읽기 및 알 수없는 길이 데이터

알 수없는 길이를 사용하여 소켓 읽기를 읽을 수있는 방법이 있습니까?

다음은 내가 작성한 코드이지만 read()에 있습니다. 이 경우

static void 
process_command (int fd) { 
    fprintf (stderr, "process_command\n"); 
    char *buffer = (char *) malloc (sizeof (char) * SIZE_TO_READ); 
    int n = 0; 
    while (1) { 
     fprintf (stderr, "."); 
     n = read (fd, buffer, SIZE_TO_READ); 
     fprintf (stderr, "bytes read = %d \n", n); 
     if (n <= 0 || n == -1) 
      break; 
     buffer = (char *) realloc (buffer, n + SIZE_TO_READ); 
    } 
    char * p = strchr (buffer, '\n'); 
    if (p) *p = '\0'; 
    fprintf (stderr, "-----> %s\n", buffer); 
    if (buffer) free (buffer); 
} 

FD

은 그냥 몇 가지 블록 (버퍼)는 0을 반환하거나 프로토콜에 따라 데이터의 끝이 있음을 볼 때까지 읽을 FILENO_STDIN

+1

'realloc()'의 결과를 인수와 동일한 변수에 대입하는 것은 안전하지 않습니다. 왜냐하면 할당이 실패 할 수 있기 때문입니다 (이 경우 이전 버퍼가 유출됩니다). 또한'strchr()'을 사용하면 나에게 안전하지 않은 것처럼 보입니다. –

+0

감사합니다. 그걸 수정합니다 – Avinash

답변

1

socket() (fcntl()O_NONBLOCK으로 전화하십시오)을 호출하여 SOCK_NONBLOCK을 전달하여 소켓 작동을 비 차단으로 만듭니다. 결과적으로 읽을 데이터가없는 경우 read() EAGAIN 또는 EWOULDBLOCK (실제로는 동일 함) 호출이 실패합니다.

또는 read() 호출 전에 특정 소켓에서 읽을 준비가 된 데이터가 있는지 확인하려면 select()을 사용할 수 있습니다.

5

입니다.

+1

내부 메모리와 가상 메모리가 모두 가득 찼을 때 오류가 표시됩니다. 그냥 충돌하지 마십시오. –

2

예상되는 바이트 수를 알 수있는 방법이 전혀없는 경우는 드뭅니다. 대부분의 프로토콜에는 데이터 길이 또는 데이터 종결자를 지정하는 방법이 있습니다. 정확히 어떤 프로토콜을 구현하고 있습니까?

+0

** ** 모든 합리적인 프로토콜은 각 메시지의 길이가 고정되어 있는지 또는 고정되었거나 얼마나 오랫동안인지 알려주는 컨텍스트가 있기 때문에 각 메시지의 길이를 확인합니다. 컨텍스트는 데이터 앞에 명시적인 길이가 될 수도 있고 문자열 끝에 null 바이트와 같은 끝 마커가 될 수도 있습니다. 그러나 데이터가 얼마나 오래 있어야 하는지를 나타내는 방법은 항상 있습니다. –

+0

이 특별한 경우에, 첫 번째 줄 바꿈은 프로토콜이 첫 줄 바꿈에서 멈추는 것처럼 보입니다. 첫 번째 줄 바꿈은 완전히 지워지고 아무 것도 완전히 무시 된 것입니다. –

+0

그렇게 확신하지 마십시오. 예를 들어, HTTP 서버는 당신에게 'Content-Length'헤더를 제공하지 않을 수 있습니다.이 헤더는 잘못 작성된 웹 응용 프로그램에서 흔히 볼 수 있습니다. –