Brak odczytu zawartości BufferedReader

Brak odczytu zawartości BufferedReader
M1
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 2 lata
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):

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

Funkcja odbierająca klienta java:

Kopiuj
   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

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

i nie wiem dlaczego.

edytowany 2x, ostatnio: mariusz198787
PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
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.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
edytowany 1x, ostatnio: PerlMonk
M1
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 2 lata
0

Kod serwera:

Kopiuj
   #!/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.

edytowany 1x, ostatnio: mariusz198787
PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
0

Sprawdź jak zachowa się taka pętla:

Kopiuj
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ą:

Kopiuj
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.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
M1
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 2 lata
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.

PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
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.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
M1
  • Rejestracja:prawie 18 lat
  • Ostatnio:ponad 2 lata
0

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

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

edytowany 1x, ostatnio: mariusz198787
PerlMonk
  • Rejestracja:około 6 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Warszawa 🐪
  • Postów:1719
0

Z tego, co rozumiem z kodu serwera

Kopiuj
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.


Nie sztuka uciec gdy w dupie sztuciec. 🐪🐪🐪
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)