Sockets with Java (server) and Python (client) without flush in python

1

Hi, I have a socket project (practice for now) and the problem is that on the client side (in python) I do not know how to clean or simulate the output buffer of the socket. The first message is sent "correctly", since it is the first and there is nothing in the socket (so to speak), but the next message is sent with the previous message, and the next message with previous plus the previous one, and so on.

I have a simple server in Java:

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

public class serpy {

    static int port = 2018;

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(port);
        System.out.println("Esperando cliente");
        Socket cli = server.accept();

        String recibido = "", enviado = "";

        OutputStreamWriter outw = new OutputStreamWriter(cli.getOutputStream(), "UTF8");
        InputStreamReader inw = new InputStreamReader(cli.getInputStream(), "UTF8");

        char[] cbuf = new char[512];

        while (true) {
            System.out.println("Esperando mensaje del cliente en python");
            inw.read(cbuf);
            for (char c : cbuf) {
                recibido += c;
                if (c == 00) {
                    break;
                }
            }
            System.out.println("Cliente dice: " + recibido);
            System.out.println("Enviar a cliente: >>>" + recibido);
            recibido = "S:" + recibido;

            outw.write(recibido.toCharArray());
            outw.flush();

            cbuf = new char[512];

        }

    }
}

Example of running the server in java:

  

Waiting for customer
  Waiting for client's message in python
  Client says: haha
  Send to client: > > > haha
  Waiting for client's message in python
  Client says: S: haha
  Send to client: > > S: haha
  Waiting for client's message in python
  Client says: S: S: haha
  Send to client: > > > S: S: haha
  Waiting for client's message in python
  Client says: S: S: S: haha
  Send to client: > > > S: S: S: haha
  Waiting for client's message in python

And the client is in Python, simple the same:

import sys
import socket as sk

host = "127.0.0.1"
port = 2018

sCliente =  sk.socket()
sCliente.connect((host, port))
print("Conectado")
inp = input("Texto para enviar:")
out = inp.encode("UTF8")
print("Se ha enviado: " + str(out.decode("UTF-8")))
sCliente.send(out)
seguir = True
while seguir:
    ins = sCliente.recv(512)
    insd = ins.decode("UTF8")
    print("Servidor retorna: " + str(insd))
    inp = input("Texto para enviar:")
    print("Enviar " + str(inp))
    salida = inp.encode("UTF8")
    print("Salida tiene antes de enviar: " + str(salida.decode("utf8")))
    lene = sCliente.send(salida)
    print("Se han enviado: " + str(lene) + " :bytes al servidor")
    if inp == "exit":
        seguir = False
    #salida = None
    ins = ""
sCliente.close()
print("Terminado")

Python execution output:

  

Text to send: haha
  Has been sent: haha
  Server returns: S: haha
  Text to send: as
  Send as
  Check out before sending: as
  They have sent: 2: bytes to the server
  Server returns: S: S: haha as
  Text to send: aa
  Send aa
  Check out before sending: aa
  They have sent: 2: bytes to the server
  Server returns: S: S: S: haha as aa
  Text to send: wqe
  Send wqe
  Output has before sending: wqe

The communication is correctly given the problem, I repeat, is how can I clean the buffer of the client socket in Python so that it sends me only the new message and not everything that has been sent?.

I do it with those objects in Java, because I want the message exchange to be merely in bytes to use the UTF8.

I practiced it only with Python and it did not give me this problem, I do not know if the error will be on the Python side.

Basically:

  • How to clean the socket buffer created from python to send a new message? If it's the problem in Python.

  • If it were in the Java part, all recommendations and advice will be very helpful.

asked by FJSevilla 07.07.2017 в 23:20
source

1 answer

1

The problem is not in the Python code or in the operation of the sockets, it is in the Java code. At no time do you clean your variable recibido , just concatenate the new bytes received to those you already had. So the echo sent to the client is not the message received at that moment but the concatenation of all the previous ones. Just make recibido an empty string at the beginning of each reading as you do in Python with ins (which, on the other hand, is not necessary):

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

public class serpy {

    static int port = 2018;

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(port);
        System.out.println("Esperando cliente");
        Socket cli = server.accept();

        String recibido = "", enviado = "";

        OutputStreamWriter outw = new OutputStreamWriter(cli.getOutputStream(), "UTF8");
        InputStreamReader inw = new InputStreamReader(cli.getInputStream(), "UTF8");

        char[] cbuf = new char[512];

        while (true) {
            System.out.println("Esperando mensaje del cliente en python");
            inw.read(cbuf);
            for (char c : cbuf) {
                recibido += c;
                if (c == 00) {
                    break;
                }
            }

            System.out.println("Cliente dice: " + recibido);
            System.out.println("Enviar a cliente: >>>" + recibido);
            recibido = "S:" + recibido;


            outw.write(recibido.toCharArray());
            outw.flush();
            recibido = "";

            cbuf = new char[512];
        }
    }
}

I'll give you the simplified Python code in case you're interested:

import sys
import socket as sk

host = "127.0.0.1"
port = 2018

sCliente =  sk.socket()
sCliente.connect((host, port))
print("Conectado")

while True: 
    inp = input("Texto para enviar: ")
    print("Enviar:", inp)
    salida = inp.encode("UTF8")
    print("Salida antes de enviar:", salida.decode("utf8"))
    lene = sCliente.send(salida)
    print("Se han enviado: {} bytes al servidor.".format(lene))   
    ins = sCliente.recv(512)
    insd = ins.decode("UTF8")
    print("Servidor retorna:", insd)
    if inp == "exit":
        break

sCliente.close()
print("Terminado")
    
answered by 08.07.2017 / 00:18
source