2017-09-09 16 views
0

네트워크의 지연, 내 PC 또는 어떤 것이 든 소켓 프로그래밍에 새로운 것이 었는지 알 수 없습니다. 내 클래스에 대한 미래의 프로젝트에 내 작품을 완화하는 간단한 프레임 워크를 구현, 잠시 동안이 일을 만들려고 노력하고 내가 데 문제에서 이러한 기능을 사용하려면 :recv() send()를 사용하여 클라이언트가 보낸 모든 데이터를 가져 오지 못함

void TCPSocket::send(const std::string& message, int flags) { 

    if (isListening || !isConnected) { 
     throw ConnectionException("Can't send message from a socket that is not connected"); 
    } 

    int msgLength = message.length(); 
    int bytesLeft = msgLength; 
    int bytesSent; 
    const char* cMessage = message.c_str(); 

    while (bytesSent < msgLength) { 

     const char* cMessageLeft = cMessage + bytesSent; 

     int result = ::send(socketFd, cMessageLeft, bytesLeft, flags); 
     if (result == -1) { 
      throw ConnectionException("Could not send message. Error: " + std::string(strerror(errno))); 
     } 

     bytesLeft -= result; 
     bytesSent += result; 

    } 

} 

std::string TCPSocket::recv(unsigned int maxlen, int flags) { 

    if (isListening || !isConnected) { 
     throw ConnectionException("Can't receive message in a socket that is not connected"); 
    } 

    char buffer[maxlen+1]; 
    int result = ::recv(socketFd, buffer, maxlen, flags); 

    if (result == -1) { 
     throw ConnectionException("Could not receive message. Error: " + std::string(strerror(errno))); 
    } 
    if (result == 0) { 
     isConnected = false; 
     throw ClosedConnection("Client closed connection."); 
    } 
    buffer[result] = '\0'; 
    std::string message(buffer); 

    return message; 

} 

그것은 단지 하나 좋은 작품 메시지, 나는 단지를 추가 할 때 가끔 가끔은 아무것도 얻을 수 없습니다, 서버는 1 메시지를 수신 얻고, 수신 전혀 문제없이 다른 실행 파일을 사용하여 보내,하지만 난 1 개 이상의 메시지를 전송하는 시도하고 내 문제가 시작 몇 가지 printf()는 모두 받아 들일 수 있습니다. 왜 이런 일이 생길까요?

클라이언트 코드 :

int main() { 
    TCPSocket cl1(0); 

    try { 
     cl1.connect("localhost", 1170); 
     for (int i = 0; i < 5; i++) { 
      //printf("Esperando 5s... "); 
      std::this_thread::sleep_for(std::chrono::milliseconds(1000)); 
      //printf("Pronto!\n\n"); 

      cl1.send("Thank you!\n"); 
      //printf("Msg enviada\n\n"); 

     } 
     cl1.close(); 
    } 
    catch(std::exception &e) { 
     std::cout << e.what() << std::endl; 
    } 
} 

서버 코드 :

int main() { 
    TCPSocket sv1(0); 

    try { 
     sv1.bind(1170); 
     sv1.listen(); 
     TCPSocket client = sv1.accept(); 
     printf("Cliente conectado\n"); 
     try { 
      for (;;) { 
       //client.send("Welcome !\n"); 
       std::cout << client.recv(256) << std::endl; 
      } 
     } 
     catch (const ClosedConnection & x) { 
      printf("Connection closed\n"); 
     } 

    } 
    catch(std::exception &e) { 
     std::cout << e.what() << std::endl; 
    } 
} 

나는 클라이언트의 코드에 printfs 주석을 제거하면

, 모든 데이터가 서버에 수신됩니다.

명확화, 5s 간격으로 메시지를 보내고 있지만 여전히 recv()는 첫 번째 메시지 만 읽습니다. client이 실행을 마칠 때까지 차단하고 나머지는 버퍼에 읽지 않습니다. 어떤 이유로 클라이언트의 코드에 printfs를 사용하면 응용 프로그램을 올바르게 실행할 수 있습니다.

+0

. TCP는 스트림 프로토콜이며 메시지 프로토콜은 아닙니다. 즉, 예상 한 모든 데이터를받을 때까지 루프에서'recv'를 호출해야합니다. "감사합니다" – selbie

+0

@selbie 나는 것을 이해하지만, 내가 왜 수신하고 한 번만 내가 그것을 5 시간을 보낸 그들이 버퍼에 있어야 것이 분명 할 때? 정말 빨리 5 번을 보내면 recv()는 모두 같은 문자열로 돌려 보낼 것입니다. 그러나 그 일은 일어나지 않습니다. –

+0

[mcve] – xaxxon

답변

1

당신은 실제로 데이터가 불확실한 것으로 보인다 보낼 것 때문에 횟수를 bytesSent를 초기화 할 것 같지 않습니다. 디자인으로

int bytesSent = 0; 
+0

은 분명히 정말 문제가되었다가, 내가, 지금 덕분에 아주 바보가 된 기분. –

+1

바보 같은 느낌이 좋습니다. 아니면 최소한 똑똑하고 어리 석다는 느낌보다 당신에게 더 낫습니다. – user4581301