2013-06-09 2 views
1

0.02 초마다 다른 프로세스로 데이터를 보내야합니다. 고주파로 소켓 통신

서버 코드 :

//set socket, bind, listen 
while(1){ 
    sleep(0.02); 
    echo(newsockfd); 
} 

void echo (int sock) 
{ 
    int n; 
    char buffer[256]="abc"; 
    n=send(sock,buffer,strlen(buffer),0); 
    if (n < 0) error("ERROR Sending"); 
} 

클라이언트 코드 :

Recieved data:abc 
Recieved data:abcabcabc 
Recieved data:abcabc 
.... 

방법 :

클라이언트 이런 식으로 뭔가를 보여줍니다

//connect 
while(1) 
{ 
    bzero(buffer,256); 
    n = read(sock,buffer,255); 
    printf("Recieved data:%s\n",buffer); 
    if (n < 0) 
    error("ERROR reading from socket"); 
} 

문제가된다 그것은 일어날까요? 나는 수면 시간을 설정하면 :

... 
sleep(2) 
... 

를이 확인 될 것입니다 :

Recieved data:abc 
Recieved data:abc 
Recieved data:abc 
... 
+0

사용하여 타이머를 선택합니다. 그것은 하나의 소켓과 타이밍으로 당신을 도와줍니다! – xaxxon

+1

2/일치하는 "recv"와 "읽기"와 "쓰기"를 혼합하는 것보다는 2/일치하는 이유는 합법적 인 이유 때문입니다. 읽기/recv는 "recv failed"를 의미하지 않는 -1을 반환합니다 (예 : EINTR). – kfsone

답변

3

sleep 그래서 sleep(0.02) 실제로 sleep(0)이며, 인수로 unsigned int합니다.

unsigned int sleep(unsigned int seconds); 

usleep(20)을 대신 사용하십시오. 이것은 마이크로 잠 것이다

int usleep(useconds_t usec); 
2

OS는 데이터를 버퍼링하는 데 자유롭게 (즉 이유 대신 단지 여러 패킷의 전체 패킷 보내지) 슬립 게다가

는 부호 정수를 취한다.

5

TCP 소켓은 프레이밍을 보장하지 않습니다. TCP 소켓을 통해 바이트를 전송하면 해당 바이트는 같은 순서로 상대방에서 수신되지만 동일한 방식으로 그룹화되지는 않습니다. 어떤 방식 으로든 분할되거나 그룹화되거나 재 그룹화 될 수 있습니다 운영 체제가 적합합니다.

프레이밍이 필요하면 각 데이터 청크가 시작하고 끝나는 위치를 나타내는 일종의 패킷 헤더를 보내야합니다. 이는 구분 기호 (예 : \n 또는 \0, 각 청크가 끝나는 곳을 나타냄) 또는 길이 값 (예 : 각 청크의 머리 부분에 표시된 숫자)의 형태를 취할 수 있습니다.

또한 다른 응답자가 말한 것처럼 sleep()은 정수를 취하므로 실제로 여기서자는 것이 아닙니다.

2

이유는 OS가 전송할 데이터를 버퍼링하기 때문입니다. 크기 나 시간에 따라 버퍼링됩니다. 이 경우 충분한 데이터를 보내지는 못하지만 OS가 전선에 꽂기 전에 대량으로 선택하기에 충분히 빠릅니다.

당신이 sleep(2)를 추가 할 때, 즉 OS가 다음 일 이전에 하나의 "ABC"를 보내도록 선택 충분히 긴이 제공됩니다.

당신은 TCP 단순히 바이트 스트림 것을 이해할 필요가있다. 메시지 나 크기에 대한 개념이 없습니다. 한쪽 끝의 와이어에 바이트를 놓고 다른 쪽 끝의 바이트를 꺼내기 만하면됩니다. 특정 일을하고 싶다면 데이터를 읽을 때 데이터를 특별한 방식으로 해석해야합니다. 이 때문에 올바른 해결책은 실제 프로토콜을 만드는 것입니다. 이 프로토콜은 "각 3 바이트가 하나의 메시지"처럼 간단하거나 크기 프리픽스를 보내는 곳에서 더 복잡 할 수 있습니다.

UDP는 또한 다른 요구 사항에 따라, 당신을 위해 좋은 해결책이 될 수 있습니다. 인수가 너무 암시 적 변환이 당신을 위해 그것을하지, 부호 INT 때문에

+0

또는 데이터 그램을 순서대로 유지하고 배달을 보장하지만 바이트 스트림이 아닌 패킷으로 유지하는 SCTP. – glglgl

2
sleep(0.02) 

효과적으로

sleep(0) 

입니다. 그래서 여기에는 전혀 잠이 없습니다. 당신은 2 microseconds.Next을 위해 잠을 sleep(2)를 사용했던 경우에도 메시지가 다른 프레임으로 전송됩니다 보장이 없습니다. 이 필요한 경우, 당신은 구분 기호의 일종을 적용해야합니다, 좀 구현

'\0'

문자를 보았다.

2

TCPIP 스택은 상당한 양의 데이터가있을 때까지 또는 응용 프로그램에서 더 이상 데이터를 가져 오지 못하고 어쨌든 얻은 정보를 보낼 때까지 데이터를 버퍼링합니다.

은 당신이해야 할 두 가지가 있습니다. 먼저, Nagle의 알고리즘을 끄십시오. 둘째로, 일종의 틀 구조를 정리하십시오.

Nagle의 알고리즘을 끄면 더 많은 정보를 보내려는 순간을 기다리지 않고 스택이 "데이터를 즉시 전송"하게됩니다. 즉, 이더넷 프레임을 채우지 않기 때문에 실제로 네트워크 효율성이 떨어집니다. 최상의 처리량을 얻으려면 점보 프레임이 필요한 기가비트를 염두에 두어야합니다. 그러나 귀하의 경우에는 처리량보다 적시성이 중요합니다.

매우 간단한 방법으로 메시지를 작성할 수 있습니다. 예를 들어, 메시지가 남을 때 남은 시간을 나타내는 정수를 먼저 보내면됩니다. 판독기 끝에서 정수를 읽은 다음 해당 바이트 수를 읽습니다. 다음 메시지에 대해 당신은 등 해당 메시지가 얼마나 오래 말하는 또 다른 정수를 보낼 것

그런 일이 괜찮습니다하지만 대단히 강력한 없습니다. ASN.1 또는 Google 프로토콜 버퍼와 같은 것을 볼 수 있습니다.

Objective System의 ASN.1 라이브러리 및 도구 (무료는 아닙니다)를 사용했으며 메시지 무결성, 프레임 등을 검토하는 작업을 잘 수행했습니다. 데이터를 읽지 않아도 좋았습니다. 한 번에 한 바이트 씩 네트워크 연결에서 효율성과 속도가 그렇게 나쁘지는 않습니다. 추가로 읽은 데이터는 그대로 유지되며 다음 메시지 디코드에 포함됩니다.

나는 Google 프로토콜 버퍼를 직접 사용하지 않았지만 비슷한 특성을 가지고있을 가능성이 있으며 다른 유사한 직렬화 메커니즘이있을 수 있습니다. 속도/효율성 이유로 XML 직렬화를 피하는 것이 좋습니다.