2012-08-08 2 views
4

나는 간단한 파이썬 TCP 서버 (나는 클래스를 사용하고있다.) 자바 클라이언트에서 데이터를 받아야하는 문제가있다. 여기자바 클라이언트에서 파이썬 소켓 recv

서버 측 코드 :

addr = InetAddress.getByName(hostname); 
SocketAddress sockaddr = new InetSocketAddress(addr, port); 
clientSocket = new Socket(); 
clientSocket.connect(sockaddr, timeoutMs); 
clientSocketDataOutputStream = new DataOutputStream(clientSocket.getOutputStream()); 
int requestCode = 1; 
clientSocketDataOutputStream.writeInt(requestCode); 
clientSocketDataOutputStream.flush(); 

내가 파이썬 서버를 시작하고 그때에 정수를 보낼 수있는 클라이언트를 실행하려고 :

class ServerRequestHandler(SocketServer.BaseRequestHandler): 
    [...] 
    def handle(self): 
     requestCode = struct.unpack('>i', self.request.recv(4))[0] 
     [...] 
    [...] 

다음은 클라이언트가 서버.

서버 측에서는 recv(4) 함수가 4 바이트를 읽지 않기 때문에 예외가 발생하지만 1 바이트 만 반환합니다.

실제로 Java 클라이언트는 정확히 4 바이트를 읽습니다. recv(1)을 4 번 호출하면 올바르게 읽습니다.

내 Java 클라이언트의 동일한 작업을 실행하는 Python 클라이언트를 작성하려고 시도했으며이 경우 서버의 recv(4)이 잘 작동합니다.

이 문제를 해결하는 방법은 무엇입니까? 바이트 단위로 소켓에서 읽는 간단한 파이썬 buffered reader function을 구현할 생각 이었지만 더 똑똑한 솔루션이 존재한다고 확신합니다.

답변

5

recv는 4 바이트를 읽을 필요가 없으며 최대 4 바이트까지 올릴 수 있습니다. 당신이 말했듯이, 당신은 recv (1)를 4 번이나 부를 수 있습니다. 당신은 size 바이트가 수신 될 때까지이

def recvall(sock, size): 
    msg = '' 
    while len(msg) < size: 
     part = sock.recv(size-len(msg)) 
     if part == '': 
      break # the connection is closed 
     msg += part 
    return msg 

이 반복적으로 sockrecv를 호출 할 수 있습니다. 그것이 내가 할 recvall 클래스의 방법을 만드는 게 좋을 것

requestCode = struct.unpack('>i', self.request.recv(4))[0] 

requestCode = struct.unpack('>i', recvall(self.request, 4))[0] 

에 변경 가까운

전에 있었다 무엇이든 반환 있도록 part == '' 경우 소켓이 닫혀 사물을 깨끗이합니다.


는 안전 소켓 클래스의 방법의 수정은 정의된다 : http://docs.python.org/howto/sockets.html

0

recv (4)는 최대 4 바이트를 읽습니다. 문서 : http://docs.python.org/library/socket.html을 참조하십시오. 간단한 버퍼링 된 리더 기능을 만드는 것이 여기에 완벽하게 수용 가능한 해결책이라고 생각합니다.

0

은 아마 당신은 io 모듈에서 뭔가를 사용할 수 있을까? 예 : BufferedRWPair.