I need to send a message from a java client program to a python server program.
Here is my code:
Java client:
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
// need host and port, we want to connect to the ServerSocket at port 7777
Socket socket = new Socket("localhost", 7777);
System.out.println("Connected!");
// get the output stream from the socket.
OutputStream outputStream = socket.getOutputStream();
// create a data output stream from the output stream so we can send data through it
DataOutputStream dataOutputStream = new DataOutputStream(outputStream);
System.out.println("Sending string to the ServerSocket");
// write the message we want to send
dataOutputStream.writeUTF("Hello from the other side!");
dataOutputStream.flush(); // send the message
dataOutputStream.close(); // close the output stream when we're done.
System.out.println("Closing socket and terminating program.");
socket.close();
}
}
Python server:
from multiprocessing.connection import Listener
address = ('localhost',7777)
while True:
with Listener(address, authkey=None) as listener
with listener.accept() as conn:
print(conn.recv())
When I try to execute this, I get the following error in Python:
OSError: got end of file during message
What am I doing wrong?
CodePudding user response:
Use of the multiprocessing module seems inappropriate in this case and is the root cause of your problem. Here's a simplified Python server that demonstrates how you could achieve your objective. Note that the server terminates after accepting and handling any single connection:
import socket
def server():
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('0.0.0.0', 7777))
s.listen()
conn, _ = s.accept()
with conn:
while (data := conn.recv(8192)):
print(data.decode())
if __name__ == '__main__':
server()
CodePudding user response:
The issue here is that the recv* functions of the multiprocessing connection expect to get a 32-bit preamble in the message that indicates the actual amount of data being transmitted. So here's what the Java part needs to look like (I haven't bothered about buffered IO - just keeping things to bare bones):
import java.io.IOException;
import java.net.Socket;
import java.io.OutputStream;
public class Client {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 7777)) {
OutputStream out = socket.getOutputStream();
byte[] dts = "Hello from the other side!".getBytes();
out.write(net(dts.length));
out.write(dts);
}
}
private static byte[] net(int n) {
byte[] buffer = new byte[4];
for (int i = 3; i >= 0; i -= 1) {
buffer[i] = (byte)(n & 0xff);
n >>>= 8;
}
return buffer;
}
}
Then, your Python server can look something like this:
from multiprocessing.connection import Listener
def main():
listener = Listener(address=('0.0.0.0', 7777), family='AF_INET', authkey=None)
with listener.accept() as conn:
print(conn.recv_bytes().decode())
if __name__ == '__main__':
main()
So, this means that your original problem is due to recv() looking at the first 4 bytes and interpreting that as the length of incoming data. But that would equate to something much larger than was actually being sent.