Reputation: 285
I have a problem with a simple python tcp server (I'm using SocketServer
class) that have to receive data from a java client.
Here the server side code:
class ServerRequestHandler(SocketServer.BaseRequestHandler):
[...]
def handle(self):
requestCode = struct.unpack('>i', self.request.recv(4))[0]
[...]
[...]
Here there is the client:
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();
I start the Python server and then I try to execute the client that have to send an integer to the server.
On the server side Python raise an exception because the recv(4)
function does not read 4 bytes, it returns only one byte.
My java client sends 4 bytes correctly in fact, if I try to call recv(1)
4 times it reads 4 bytes correctly.
I tried to write a Python client that execute the same operation of my java client and in this case the server's recv(4)
works well.
How to solve this problem? I thought to implement a simple python buffered reader function
that reads from socket byte by byte but I'm sure that a smarter solution exists.
Upvotes: 4
Views: 1827
Reputation: 36872
the recv doesn't have to read 4 bytes, it just grabs whatever is there up to a max of four bytes. Since, as you said, you can call recv(1) 4 times. you can do this
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
this will repeatedly call recv
on sock
until size
bytes are received. if part == ''
the socket is closed so it will return whatever was there before the close
so change
requestCode = struct.unpack('>i', self.request.recv(4))[0]
to
requestCode = struct.unpack('>i', recvall(self.request, 4))[0]
I'd suggest making recvall
a method of your class to make things cleaner.
this is a modification of a method from the safe socket class defined here: http://docs.python.org/howto/sockets.html
Upvotes: 5
Reputation: 10551
Maybe you could use something from io module? BufferedRWPair for example.
Upvotes: 0
Reputation: 1257
recv(4) will read a maximum of 4 bytes. See the docs: http://docs.python.org/library/socket.html . I think making a simple buffered reader function is a perfectly acceptable solution here.
Upvotes: 0