Brak odczytu zawartości BufferedReader

0

Witam,

Napisłem prosta aplikację na androida, która odbiera z serwera dane (serwer python). O ile komunikacja

Funkcja wysyłająca dana z serwera python (standardowa metoda wysyłajaca dane w komunikacji socketowej):

   tmp="Operation OK"
   send(bytes(tmp,'UTF-8'))

Funkcja odbierająca klienta java:

   public void run() {

            try {
                InetAddress serverAddr =  InetAddress.getByName(SERVER_IP);
                Log.d("ClientActivity", "C: Connecting...");
                socket = new Socket(serverAddr, SERVERPORT);
                connected = true;
                String msg="";
                BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(),StandardCharsets.UTF_8));
                while (connected) {
                    if(arePasswordsEqual(et2.getText().toString(),et3.getText().toString())==true) {
                        Log.d("ClientActivity", "C: Sending command.");
                        String strL = "Test";
                        PrintWriter out = new PrintWriter(new BufferedWriter(
                                new OutputStreamWriter(socket.getOutputStream())),
                                true);
                        out.println(strL);
                        Log.d("ClientActivity", "C: Sent.");
                    }
                    else {}
                    String response ;
                    while ((response = in.readLine()) != null) {
                        Log.d("ClientActivity", "works before" );
                        msg+=response;
                        Log.d("ClientActivity", "works after" );
                    }
                    Log.d("ClientActivity", "Get:" + msg);
                    msg="";
                    connected=false;
                }


                socket.close();
                Log.d("ClientActivity", "C: Closed.");

            } catch (UnknownHostException e) {
                e.printStackTrace();
                connected = false;
            } catch (IOException e) {
                e.printStackTrace();
                connected = false;
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }

        }

Niestety program nie wchodzi do pętli

   while ((response = in.readLine()) != null) 

i nie wiem dlaczego.

0

Co to za serwer? Też jakaś twoja apka? Jeśli tak, to pokaż.
Funkcja readLine zwraca NULL kiedy napotka koniec strumienia (EOF). A koniec strumienia następuje kiedy serwer zamyka połączenie.
Przykładowa komunikacja (np. HTTP) w uproszczeniu wygląda tak:

  • serwer nasłuchuje
  • klient rozpoczyna wysyłanie danych do serwera
  • serwer odbiera dane od klienta
  • serwer kończy transmisję klient - serwer
  • serwer wysyła dane do klienta
  • serwer kończy transmisję serwer - klient.

Upewnij się, że serwer zamyka połączenie i nie wysyła pustej linii.

0

Kod serwera:

   #!/usr/bin/python           # This is server.py file

import socket               # Import socket module
import pymysql.cursors



def dataBaseOperation(id,login,password):
	try:
		db = pymysql.connect(host="localhost",    # your host, usually localhost
							 user="root",         # your username
							 passwd="pass",  # your password
							 db="tmp")        # name of the data base

		cur = db.cursor()
		cur.execute("insert into uzytkownicy (id,login,password) values ('%s','%s','%s')" %(id,login,password))
		
		db.commit()
		sendFlag=True
	except:
		db.rollback()
		print('Operation failed.')
		sendFlag=False
	finally:
		if db != None:
			db.close()
	return sendFlag

			
def main():
	s = socket.socket()         # Create a socket object
	host = socket.gethostname() # Get local machine name
	ip=socket.gethostbyname(host)
	print (ip)
	port = 7777                # Reserve a port for your service.
	s.bind((host, port))        # Bind to the port
	data=''
	s.listen(5)                 # Now wait for client connection.
	
	while True:
		c, addr = s.accept()     # Establish connection with client.
		fromClient=''
		print('From: ',addr)
		while True:
			data=c.recv(1024) 
			if not data: break
			fromClient+=data.decode().rstrip()
			if fromClient.startswith("Start"):
				data=fromClient.split(";")
				optmp=dataBaseOperation(data[1],data[2],data[3])
				if optmp is True:
					tmp="Operacja powiodła się"
					#print(tmp)
					c.send(bytes(tmp,'UTF-8'))
					#print(c.send(bytes(tmp,'UTF-8')))
					tmp=''
				else:
					tmp="Operacja nie powiodła się"
					c.send(bytes(tmp,'UTF-8'))
					tmp=''
	c.close()

if __name__ == "__main__":
    main()

Sprawdzałem while z readline dla warunku ==NULL, ale też tę pętlę omija.

0

Sprawdź jak zachowa się taka pętla:

while (true) {
    response = in.readLine();

    if (response == NULL || response.isEmpty()) {
        break;
    }

    Log.d("ClientActivity", "works before" );
    msg+=response;
    Log.d("ClientActivity", "works after" );
}

Jeśli to nic nie da, sprawdź co się stanie z taką pętlą:

int bufferSize = 4096;
int bytesRead = -1;
char buffer[] = new char[bufferSize];

while (true) {
	Arrays.fill(buffer, 0);
	bytesRead = in.read(buffer);
	
	if (bytesRead <= 0) {
		System.out.println("Brak danych " + bytesRead);
	}

	Log.d("ClientActivity", "works before" );
    msg += new String(Arrays.copyOfRange(buffer, 0, bytesRead));
    Log.d("ClientActivity", "works after" );
}

Zobaczysz tutaj ile danych jest przesyłanych.

0

Dla pierwszego przypadku sytuacja ta sama co poprzednio, ale juz dla drugiego działa ok (zawartość pętli jest osiągalna) i wszystkie dane wysłane przez serwer trafiają do klienta.

0

Dopiero zauważyłem, że w drugiej wersji pętli nie dodałem instrukcji break. Ale z tym chyba sobie poradzisz.
Warto zwrócić uwagę, że przy przesyłaniu tekstu w kodowaniu UTF-8 liczba znaków nie musi równać się liczbie bajtów.

0

Tak, poradze sobie. Dzięki za pomoc. Jednak nadal nie rozumiem dlaczego to nie działało

   while ((response = in.readLine()) != null) {

0

Z tego, co rozumiem z kodu serwera

if not data: break

jeśli nie odczyta danych, kończy pętlę i nie wysyła nic klientowi. Klient wtedy dostanie null. W trybie nieblokującym normalnie wygenerowałbyś nowe zdarzenie w takiej sytuacji zamiast czekać uparcie, że coś tam będzie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1