Ninja Dude
Ninja Dude

Reputation: 1392

Python server and Java client socket

Server in python

import socket
from sys import getsizeof

host = ''
port = 5560

storedValue = "Yo, what's up?"

def setupServer():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    print("Socket created.")
    try:
        s.bind((host, port))
    except socket.error as msg:
        print(msg)
    print("Socket bind comPlete.")
    return s

def setupConnection():
    s.listen(1) # Allows one connection at a time.
    print("Waiting for client")
    conn, address = s.accept()
    return conn

def GET():
    reply = storedValue
    return reply

def REPEAT(dataMessage):
    reply = dataMessage[1]
    return reply

def dataTransfer(conn, s):
    # A big loop that sends/receives data until told not to.
    while True:
        # Receive the data
        data = conn.recv(1028) # receive the data
        data = data.decode('utf-8')
        data = data.strip()
        print("data value from client: " + data)
        # Split the data such that you separate the command
        # from the rest of the data.
        command = str(data)
        print("data length from client: " + command)
        reply = ""
        if command == "GET":
            reply = GET()
            print (command)
            print (reply)
        elif command == 'REPEAT':
            reply = REPEAT(dataMessage)
        elif command == 'EXIT':
            print("Our client has left us :(")
            break
        elif command == 'KILL':
            print("Our server is shutting down.")
            s.close()
            break
        else:
            reply = 'Unknown Command'
        # Send the reply back to the client
        conn.sendall(bytes(reply, 'utf-8')) 
        print("Data has been sent!")
    conn.close()

s = setupServer()

while True:
    try:
        conn = setupConnection()
        dataTransfer(conn, s)
    except:
        break

Client in java

import java.io.*;   
import java.net.*; 
import java.util.*;

public class pcClient {

    public static void main(String[] args) {  

        Socket rpiSocket = null; 
        DataInputStream in = null;
        PrintStream out = null;

        try {
            rpiSocket = new Socket("localhost",5560); 
            out = new PrintStream(rpiSocket.getOutputStream());
            in = new DataInputStream(new BufferedInputStream(rpiSocket.getInputStream()));
        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: hostname");
        } catch (IOException e) {
            System.err.println("Couldn't get I/O for the connection to: hostname");
        }

        try {
        if (rpiSocket != null && out != null && in != null) {
            while(true) {
                System.out.println("Please input your command ");
                Scanner scanner = new Scanner(System.in);
                String command = scanner.nextLine();

                if(command.equals("KILL")) {
                    break;
                }

                System.out.println("Sending command to client: " + command);
                out.println(command);

                byte[] bytes = new byte[1024];

                in.read(bytes);
                String reply = new String(bytes, "UTF-8");
                System.out.println("Reply from server: " + reply.trim());
            }
        }

            rpiSocket.close();
            System.out.println("Connections closed successfully");
        }
        catch (IOException e) {
            System.err.println("IOException:  " + e);
        }
    }
}

I have the python server above and a java client. The java client takes input from user and sends it to the python. All this is working well. However, the python server is receiving the string from the java and an additional empty string. For example, from the java client, when i send the word "GET", the python server is able to receive this GET and print "Yo, what's up?". However, it goes back to the "While True" and immediately also additionally receives an empty string right after and starts checking the condition with that empty string. I tried to trim the strings received from the java client. How can i solve this? Thanks.

Upvotes: 1

Views: 1346

Answers (2)

Nipun Talukdar
Nipun Talukdar

Reputation: 5387

The problem is occurring because of out.println(command) you are using from the java program. It is sending the command and also some newline characters over the socket. If you replace it with out.print(command), the problem will be solved.

println may be sending the main string and the newline characters internally in two calls, I am not sure. But ideally, every "command" from the client side should first include the length of the command string, and then the real command. Server side may need buffering or splitting of the input data if recv returns more than or less than the required number of bytes.

There is a small python library datachunkpy which may help to split and process the commands (https://pypi.python.org/pypi/datachunkpy/1.0.0)

Upvotes: 1

Michael Butscher
Michael Butscher

Reputation: 10959

conn.recv() returns as much data as immediately available (e.g. one packet). The Java runtime library on the other hand is free to subdivide the sent data into multiple packets. I guess that it sends one packet with the "GET" and another packet with the final newline.

A solution would be for the server to wait and collect input from stream until a newline is found to finish the command.

Upvotes: 1

Related Questions