2014-02-26 1 views
0

나는 간단한 C++ 클라이언트/서버 쌍을 썼다. 서버는 소켓 수용 (accept)에서 프로세스를 포크 (fork) 한 다음 클라이언트로부터의 패킷을 기다린 다음 다른 패킷으로 응답합니다. 클라이언트는 서버에 패킷을 보내고 응답을 기다립니다. 나는 송신 직전에 클라이언트에 타이밍 코드를 가지고 있고 수신 직후에 타이밍 코드를 가지고있다.localhost에 TCP 패킷을 보내는 데 너무 오래 걸리는 이유는 무엇입니까?

로컬 상자에서 서버와 클라이언트를 모두 실행하고 로컬 호스트에 클라이언트를 연결하고 있습니다.

나의 타이밍에서 중간 대기 시간은 약 2 밀리 초인 것으로 보인다. 네트워크에서 아무 것도 보내지 않고 있다고 가정하면 2 밀리 초 대기 시간은 나에게 너무 높습니다.

아무도 내가 왜 이렇게 높은 대기 시간을 보았는지 또는 루프백 주소에 대해이 시간이 현실적인지 설명 할 수 있습니까?

저는 Linux Ubuntu 12.04입니다. 나는 TCP 소켓 시스템 호출을 직접적으로 사용하고있다. (즉, accept, listen, send, receive).

서버 본체 :

while (1) 
{ 
    ++msgNum; 

    sin_size = sizeof their_addr; 
    new_fd = accept(sockfd, (struct sockaddr*) &their_addr, &sin_size); 
    if (new_fd == -1) 
    { 
     perror("accept"); 
     continue; 
    } 

    inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr*) &their_addr), 
     s, sizeof s); 
    printf("server: got connection from %s\n", s); 

    if (!fork()) 
    { 
     close(sockfd); // child doesn't need the listener 

     MyMsg msg; 
     strcpy(msg.buf, "Hello world"); 

     for (int i = 1; i <= NUM_TEST_MSGS; ++i) 
     { 
      msg.id = i; 

      int numbytes = 0; 
      int bytesRecv = 0; 

      while (numbytes < MSG_LEN) 
      { 
       int sendSize = MSG_LEN - numbytes; 
       if ((bytesRecv = send(new_fd, ((char*) &msg) + numbytes, 
         sendSize, 0)) == -1) 
       { 
        perror("send"); 
        exit(1); 
       } 
       numbytes += bytesRecv; 
      } 

      assert(numbytes == MSG_LEN); 

      //printf("Server sent %d num bytes\n", numbytes); 
     } 

     printf("Server finished sending msgs.\n"); 

     close(new_fd); 
     exit(0); 
    } 
    close(new_fd); 
} 

클라이언트 본문 :

for (int i = 1; i <= NUM_TEST_MSGS; ++i) 
{ 
    MyMsg msg; 

    int numbytes = 0; 
    int bytesRecv = 0; 

    int start = rdTsc.Rdtsc(); 

    while (numbytes < MSG_LEN) 
    { 
     int recvSize = MSG_LEN - numbytes; 
     if ((bytesRecv = recv(sockfd, ((char*) &msg) + numbytes, recvSize, 0)) == -1) 
     { 
      perror("recv"); 
      exit(1); 
     } 

     numbytes += bytesRecv; 
    } 

    int end = rdTsc.Rdtsc(); 

    perfCounter.Track(end - start); 

    if (numbytes != MSG_LEN) 
    { 
     printf("COMP FAILED: %d %d\n", numbytes, MSG_LEN); 
    } 

    assert(numbytes == MSG_LEN); 

    if (i != msg.id) 
    { 
     printf("Msg %d id %d \n", i, msg.id); 
    } 

    //if (numbytes != MSG_LEN) printf("GOT WEIRD SIZE %d\n", numbytes); 
    assert(msg.id == i); 

    //printf("client: received %d num bytes id %d body '%s'\n", numbytes, msg.id, msg.buf); 

    if (i % 1000 == 0) 
    { 
     printf("Client: Received %d num msgs.\n", i); 
    } 
} 

printf("Client: Finished successfully.\n"); 

close(sockfd); 
+0

코드를 게시하면 더 잘 도와 드리겠습니다. – MrDuk

답변

0

2ms의 확실히 아마 커널 버퍼를 떠난 적이 뭔가 높은 소리가 난다. 시간 스탬핑에 사용 된 함수에서 실제로 부정확 할 수도 있습니다.

+0

글쎄 내 시간 스탬프는 시스템 호출이 아닌 tsc 카운터를 사용한다. 그리고 나는 이전에이 카운터들을 다른 목적으로 사용했습니다. 그래서 타임 스탬프를 배제 할 수 있습니다. –

+0

메시지의 크기는 어느 정도입니까? (printf() 및/또는 상시 개폐를 반복하는) 눈에 띄는 부분은 분명히 알 수 없으므로 이제는 버퍼를 늘리는 것보다는 차단하기로 결정한 Linux와 같은 정말로 투기적인 것들에 대해 다루고 있습니다. – Remy

+0

그리 크지 않습니다. 1000 바이트. 그것은 nagel-ing 일 수 있었습니까? –

관련 문제