2009-10-16 4 views
1

데이터 전송을 위해 유닉스 scoket을 사용 중입니다 (SOCK_STREAM 모드)유닉스 소켓 : 하나의 "보내기"통화로 큰 데이터를 보내는 방법은 무엇입니까?

100k 개 이상의 문자열을 보내야합니다. 첫째, 문자열 길이를 전송합니다. sizeof (int) 바이트입니다.

length = strlen(s) 
send(sd, length, sizeof(int)) 

은 그 때 나는 전체 문자열을

bytesSend = send(sd, s, length) 

를 보내하지만 놀랍게도은 "bytesSend"는 "길이"보다 작습니다.

큰 문자열이 아닌 문자열을 보내면 잘 작동합니다. 누락 된 시스템 호출 "보내기"에 몇 가지 제한이있을 수 있습니다 ...

답변

11

send 시스템 호출은 일 것입니다. 프로그램에 다른 유용한 작업이있을 수 있기 때문입니다. 확실히 데이터를 보내고 다른 컴퓨터가 응답을 보내길 기다리지 않으려 고합니다. 그러면 처리량이 높아질 수 있습니다.

그래서 모든 send은 실제로 보내는 데이터를 대기열에두고 프로그램에 제어권을 반환합니다. 커널 이 전체 메시지를 커널 메모리에 복사 할 수 있지만 커널 메모리를 많이 소모합니다 (좋지 않습니다).

대신 커널은 합리적인만큼의 메시지 만 대기시킵니다. 나머지 데이터를 다시 전송하는 것은 프로그램의 책임입니다.

루프를 사용하여 처음 전송되지 않은 데이터를 보내십시오.

while(length > 0) { 
    bytesSent = send(sd, s, length); 
    if (bytesSent == 0) 
     break; //socket probably closed 
    else if (bytesSent < 0) 
     break; //handle errors appropriately 
    s += bytesSent; 
    length -= bytesSent; 
} 

수신 측에서는 동일한 작업을 수행해야 할 가능성이 큽니다.

+0

마치 그것을 할 수있는 유일한 방법입니다. 고마워요 – Nelly

+0

어 ... 뭐라고 요? :) – Nelly

+0

Hehe ... 그래서 내가 너무 늦게까지 머물게하고있다. – Artelius

1

처음 send() 호출이 잘못되었습니다. 당신은 등등 다양한 플랫폼에서, 엔디 언으로,

bytesSend = send(sd, &length, sizeof(int)) 

또한,이 몇 가지 고전 위험에 실행 :, int의 크기 즉를() 보내 전달하는 데이터의 주소를해야합니다.

+0

게시하는 동안 여기에 잘못 인쇄했습니다 ... 내 코드에서 전화가 정확합니다 .. – Nelly

관련 문제