2012-05-07 2 views
1

파이썬 소켓에 문제가 있습니다.TCP 소켓 : 이중 메시지

나는 서로 while 1 루프에서 서로 데이터를 보내는 TCP 서버와 클라이언트를 가지고있다.

구조 모듈 (struct.pack("hh", mousex, mousey))에서 2 단락을 패키지화합니다. 그러나 때로는 recv 다른 컴퓨터의 데이터를 보내면 2 개의 메시지가 함께 붙어있는 것처럼 보입니다. 이 독수리의 알고리즘인가요? 여기

enter image description here

일 정확히 무엇? 미리 감사드립니다.

+0

아니요 Nagle의 알고리즘이 아닙니다. TCP는 데이터를 복제하지 않습니다. 사람들이 버그가 어디에 있는지 알려주도록 코드를 게시해야합니다. – EJP

답변

1

다른 포스터에 동의합니다. "TCP가 그 일을합니다." TCP는 여러분의 바이트가 올바른 순서로 도착 함을 보장하지만 도착하는 청크의 크기에 대해서는 보장하지 않습니다. TCP를 사용하여 여러 개의 recv로 단일 송신을 분할하거나 심지어 예를 들어 aabb를 분할하는 것도 허용됩니다. ccdd를 aab, bcc, dd로 변환합니다.

나는 파이썬에서 관련 문제를 다루는 함께이 모듈을 넣어 : http://stromberg.dnsalias.org/~strombrg/bufsock.html 그것은이 오픈 소스 라이센스하에이고 UCI가 소유하고 있습니다. CPython 2.x, CPython 3.x, Pypy 및 Jython에서 테스트되었습니다.

HTH

0

다른 소스 끝에서 보내는 것과 동일한 크기로 로컬 소켓에서 데이터를 읽을 수 있다고 가정 할 수 없습니다. 보시다시피, 때로는 대개 사실 일 수 있지만 결코 그렇게 신뢰할 수는 없습니다. 그보다는 TCP가 보증하는 바는 결국 한쪽에 들어가는 것이 결국 다른쪽에 나올 것이라는 것입니다. 이 없거나, 재 시도 같은 프로토콜에 내장 된 방법으로는 불가능한 경우라면, 모든 것이 오류로 깨질 것입니다. .

Nagle이 원인 중 하나 일뿐입니다.

1

실제 코드를 확인해야하지만 sendn 바이트가 항상 정확히 n 바이트로 표시 될 것으로 예상됩니다.

TCP 스트림이 그렇게 작동하지 않습니다. UDP 나 STCP 또는 RDS과 같은 "데이터 그램"(레코드 지향)과는 대조적으로 "스트리밍"프로토콜입니다.

고정 데이터 크기 프로토콜 (또는 다음 청크 크기를 미리 예측할 수있는 곳)의 경우 스트림 소켓에 자신 만의 "데이터 그램 형 수신기"를 만들 수 있습니다.이 때 간단히 recv() 루프를 통해 얻을 수 있습니다 정확히 n 바이트 :

def recv_n_bytes(socket, n): 
    "attempt to receive exactly n bytes; return what we got" 
    data = [] 
    while True: 
     have = sum(len(x) for x in data) 
     if have >= n: 
      break 
     want = n - have 
     got = socket.recv(want) 
     if got == '': 
      break 
    return ''.join(data) 

(검증되지 않은, 파이썬 2.x에서 코드; 반드시 효율적이지, 등).