2014-11-03 1 views
1

유닉스에서 C의 소켓을 통해 쓰거나 읽어야하는 바이트 수에 대해서는 의심의 여지가 있습니다. 나는 1024 바이트를 보내는 데 익숙해졌지만, 짧은 문자열을 보낼 때 이것은 때로는 너무 많이 발생합니다.소켓에 몇 바이트의 읽기/쓰기를해야합니까?

파일에서 문자열을 읽었는데이 문자열이 몇 바이트인지 알지 못합니다. 매번 바뀔 수 있으며, 10, 20 또는 1000 일 수 있습니다. 나는 단지 < 1024임을 알고 있습니다. 따라서 코드를 작성할 때 클라이언트 측에서 읽을 바이트 크기를 알지 못합니다 (서버에서 strlen()을 사용할 수 있음). 그래서, 파일에서 읽은 문자열의 길이에 관계없이 항상 최대 바이트 수 (이 경우 1024)를 읽는 유일한 해결책입니까?

read(socket,stringBuff,SIZE); 

SIZE 10 대신 내가 10 바이트 문자열을 읽으려면 1024의 경우 더 나은되지 않을 것 :이 코드 예를 들어

?

+0

'recv()'는 소켓을 통해 수신 한 바이트 수를 반환합니다. – timrau

+1

다른 질문을 광고하는 데 하나의 질문을 사용하지 마십시오. –

+0

@timrau 네, 나도 알아, 그래도 읽을 줄 알아.하지만 내가 틀렸다고 생각하지 않는다면, read 호출을 할 때 read (socket, stringBuff, SIZE)와 같은 것을 써야하고 SIZE에서 읽으려는 문자의 수. 내가 10 문자 문자열을 읽는다면 크기가 1024 대신 10 인 경우 더 좋지 않겠는가? – testermaster

답변

4

질문에있는 코드에서 읽어야 할 10 바이트 만있는 경우 SIZE이 10 바이트, 1,024 바이트 또는 1,000,024 바이트인지 여부는 아무런 차이가 없습니다. 여전히 10 바이트 만 읽습니다. 유일한 차이점은 여러분이 설정 한 메모리의 양과, 최대 1,024 바이트의 문자열을받을 수 있다면 어쨌든 많은 메모리를 따로 보관해야한다는 것입니다.

그러나 실제로 읽는 바이트 수에 관계없이 read()이 실제로 다른 수의 읽을 가능성에 대비해야합니다. 특히 네트워크에서 전송 지연이 발생할 수있는 경우 서버가 1,024 바이트 문자열을 전송하는 경우에도 클라이언트가 read()을 호출 할 때까지 해당 바이트 수 미만이 도착했을 수 있습니다. 1,024.

따라서 항상 read() 전화에서 입력을 받아야 할 필요성에 대비해야합니다. 즉, 입력을 읽었을 때를 알 필요가 있다는 것을 의미합니다. read()이 완료되었다는 사실을 알리는 것은 혼자만의 의지 할 수 없습니다. 첫 번째 메시지를 읽기 전에 서버가 하나 이상의 메시지를 보낼 수 있다면 분명히이 메시지에 의존 할 수는 없습니다.

  1. 항상 같은 크기 메시지, 필요한 경우 아마도 제로와 작은 문자열을 패딩을 보내

    당신은 세 가지 옵션이 있습니다. 이것은 대개 TCP 스트림에 대해 차선책입니다. 이 바이트 수를 정확히받을 때까지 읽으십시오.

  2. 메시지가 끝났을 때 알려주는 일종의 감시 메커니즘이 있습니다. 개행 문자, CRLF, 공백 행 또는 한 행의 공백 행 또는 사용자의 프로토콜에 맞는 점이 될 수 있습니다.이 센티넬을받을 때까지 계속 읽으십시오. 한 번에 한 문자 씩 비효율적 인 시스템 호출을 피하려면이 작업을 잘 수행 할 수 있도록 일종의 버퍼링 메커니즘을 구현해야합니다. 서버에서 회선이 단일 '\n' 문자로 전송되었다고 확신 할 수 있다면 fdopen() 및 표준 C I/O 라이브러리를 사용하는 것이 좋습니다.

  3. 서버가 메시지의 크기를 알려주거나 (초기 고정 길이 필드에서 또는 포인트 2에서와 같은 종류의 센티널 메커니즘 사용) 서버에 해당 바이트 수가 나타날 때까지 계속 읽습니다. .

+0

감사합니다. 완벽한 답변입니다! :) – testermaster

2

read() 시스템 호출은 하나 이상의 바이트를 읽을 수 있거나 오류가 발생할 때까지 차단됩니다.

요청한 바이트 수를 읽지는 않습니다. TCP 소켓을 사용하면 여전히 read()이 요청한 것보다 적은 수를 반환하는 것은 매우 일반적입니다. 네트워크를 통해 전파되는 바이트를 반환 할 수 없기 때문입니다.

따라서 반환 값 read()을 확인하고 원하는 모든 것을 얻지 못하면 더 많은 데이터를 얻으려면 다시 호출해야하며, 모든 것을 얻을 때까지 다시 호출해야합니다.

+0

도움 주셔서 감사합니다! – testermaster

관련 문제