1
votes

I have a Python server and a java client. when a string is sent from java to python, it's not complete. Example:

Java Code Sending: Helloooooooooo

Recieved in Python as:

he

lloooooooo

oo

here are the codes

Python server:

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

server_address = ("localhost", 10000)
print 'starting up on %s port %s' % server_address
sock.bind(server_address)

sock.listen(5)

while True:
     print 'waiting for a connection'
     connection, client_address = sock.accept()

     try:
         print 'connection from', client_address

         while True:
             data = connection.recv(1024)
             print 'received: ' + data
             print type(data)
             if data:
                 print 'sending data back to the client'
                 connection.sendall(data)
             else:
                 print 'no more data from', client_address
                 break

     finally:
         connection.close()

Java Client:

package server;

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

class Reciever_test {
 public static void main(String args[]) throws Exception {
        String sentence;
        String modifiedSentence;
        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost", 10000);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    while(true)
    {
        sentence = inFromUser.readLine();
        outToServer.writeBytes(sentence + "\n");
        modifiedSentence = inFromServer.readLine();
        System.out.println("FROM SERVER:" + modifiedSentence);
    }

    //clientSocket.close();
}

}

2
To clarify, do you want the python side to print the whole string at once, and not parts of it?craigsparks
yes, exactly. I want the whole string because I am gonna use it later as identifier for which operation I will useOmar Amr
Then you have to collect the data from the socket until it is complete, maybe until is contains \n.Klaus D.
yes, but i was searching if there is a direct solution.Omar Amr

2 Answers

0
votes

In vain of what Klaus D.is saying, the recv guarantees how much data at most it will wait for, it might decide to handle what it has before the size is reached. I used a simple buffer, although I am sure there might be better ways:

import socket
import atexit

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ("localhost", 10000)
print ('starting up on %s port %s' % server_address)
sock.bind(server_address)

sock.listen(5)

def close(connection):
    connection.close()

while True:
     print ('waiting for a connection')
     connection, client_address = sock.accept()
     atexit.register(close, connection)

     try:
         print ('connection from', client_address)

         buffer=[]
         while True:

             data = connection.recv(1024)
             for b in data:
                buffer.append(b)
             print ('received: ' + str(data))
             print (type(data))

             if str(buffer[-1]) == '\n': #if changed to use the buffer to decide when done receiving, the newline is the terminator
                 print ('sending data back to the client')
                 connection.sendall(''.join(buffer))
                 buffer = []
             # else:
             #     print ('no more data from', client_address)
             #     break

     finally:
         close(connection)

The atexit is to close the socket gracefully in case your program crashes

0
votes

Java Client: Just changed the way i send data to server.

 public static void main(String args[]) throws Exception {
    String sentence;
    String modifiedSentence;
    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
    Socket clientSocket = new Socket("localhost", 10000);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
    Scanner sc = new Scanner(System.in);
    while(true)
    {


        while (true) {
            String input = sc.nextLine();
            out.print(input);
            out.flush();
            modifiedSentence = inFromServer.readLine();
            System.out.println("FROM SERVER:" + modifiedSentence);
        }
    }

Python Server: The way I respond had to be changed too(using send instead of sendall)

while True:
print 'waiting for a connection'
connection, client_address = sock.accept()

try:
    print 'connection from', client_address

    while True:
        data = connection.recv(4096)
        print data
        print type(data)
        if data:
            print 'sending data back to the client'
            connection.send(data + "\n")
        else:
            print 'no more data from', client_address
            break

finally:
    connection.close()