2016-09-25 11 views
1

죄송 나쁜 영어이상한 행동

이유는 서버에 두 send() -s, 클라이언트에 두 recv() -s를, 때로는 처음 recv()이있는 경우 첫 번째 콘텐츠를 가져 오지 않고 서버에서 send()의 내용을 가져오고 다른 하나는 의 "만료되었으며 적절한"내용을 recv()이 처리하도록 하시겠습니까?

어떻게하면 다른 방식으로이 작품을 얻을 수 있습니까?

답변

1

이것은 의도적으로 설계된 동작입니다.

TCP 스트림은 두 종점 사이에서 바이트를 보낼 수 있지만 전송은 메시지 기반이 아닌 스트림 기반입니다.

메시지를 보내려면 인코딩 할 필요가 있습니다. 예를 들어 수신자에게 본문에 대해 예상되는 바이트 수를 알리는 "크기"필드를 추가하는 등의 방법으로 인코딩해야합니다.

100 바이트를 보낸 다음 다른 100 바이트를 보내면 두 개의 다른 읽기 명령에서 수신기가 한 번에 200, 심지어는 50 + 150이 표시 될 가능성이 높습니다. 메시지 경계를 원하면 직접 데이터에 넣어야합니다.

메시지를 보낼 수있는 하위 레이어 (데이터 그램)가 있지만 크기가 제한되어 있으며 전송이 보장되지 않습니다 (즉, 메시지가 손실되거나 복제되거나 두 개의 메시지가 전송 될 수 있습니다 다른 순서로 도착합니다). TCP 스트림은이 데이터 그램 서비스의 상단에 구축되며 두 끝점간에 데이터를 안정적으로 전송하는 데 필요한 모든 논리를 구현합니다.

ZeroMQ과 같이 신뢰할 수있는 메시지 전달을 제공하도록 설계된 라이브러리가 있습니다.

+0

하지만 두 번째 'send()'가 첫 번째 'rec()'에 아무 것도 보내지 않도록하려면 어떻게해야합니까? 당신의 솔루션은 저에게 "텍스트 2"를 'send() 2'에서 '텍스트 1'과 섞지 않도록 'recv() 1'에서 받아 들여야합니다. 하지만 보낸 사람과 보낸 사람이 텍스트를 보낸 것을 기다리는 사람이 없으므로 'send() 2'데이터가 손실됩니다. 정확한 보내기와 정확한 recv 사이에서 어떻게 동기화 될 수 있습니까? –

+0

@ dfsfg 할 수 없습니다. 이것이 바로이 답변의 핵심입니다. 기능은 그렇게 작동하지 않습니다. –

0

대부분 SOCK_STREAM 유형 소켓을 사용합니다. 이 소켓은 TCP 소켓이므로 데이터를 한쪽으로 밀어 넣고 다른 쪽에서 같은 순서로 누락 된 청크는 없지만 구분 기호는 없습니다. 따라서 send()은 현재 데이터를 전송하고 recv()은 현재 순간까지 사용할 수있는 모든 데이터를 수신합니다.

SOCK_DGRAM을 사용할 수 있으며 UDP가 사용됩니다. 그러나이 경우 모든 send()은 데이터 그램을 보내고 recv()은 데이터 그램을 받게됩니다. 그러나 데이터 그램을 섞거나 분실하지 않는다는 보장은 없으므로 이러한 문제를 직접 처리해야합니다. 또한 최대 데이터 그램 크기에는 제한이 있습니다.

또는 TCP 연결을 고수 할 수 있지만 구분 기호를 직접 보내야합니다.