TCP Verbindung (Java Client und Visual Basic Server)

Tach zusammen,

Ich bin mittlerweile einige zeitlang mit diesem Problem beschäftigt:
Ich will eine Server-Client TCP-Verbindung herstellen. Vorher habe ich beide als VB-Variante gebastelt, lief auch alles Super.
Jetzt will ich mit einem Android-Gerät via Java einen TCP-Client mit meinem Server verbinden lassen.
Das Problem ist folgendes:

Ich starte den Server
Dieser ist empfangsbereit und wartet auf Clientverbindung
Der Client verbindet sich mit dem Server
Der Client schickt im eine Nachricht ("200")
Der Server empfängt sofort die Nachricht ("200")
Der Server sendet Antwort ("300")
Es dauert jetzt 10 Sekunden
Der Client empfängt Nachricht ("300") und Verbindung wird abgebrochen.

Die Verbindung wird bei mir automatisch nach 10 Sekunden unterbrochen,
also empfängt der Client die Nachricht erst beim Abbruch.

Warum dauert es solange zum zurücksenden? Ich habe den gleichen Server auch für meinen TCP Client für Visual Basic programmiert und dort sind keine Probleme. Was mache ich falsch?
Ich lese ja "zeilenweise". Kann das sein, dass ich da irgendwo etwas vergessen habe? Zeilenabschluss beim Server? Dort schreib ich ja nicht zeilenweise.

Hier mal der Code (ein wenig vereinfacht)

Der Servercode, läuft unter Windows 2003 Server

Dim listener As New TcpListener(50000)
listener.Start()
While True
If listener.Pending Then
Dim client As TcpClient = listener.AcceptTcpClient
Dim stream As NetworkStream = client.GetStream
Dim responsestring As String
Dim clientdata As String
Dim sendbytes As [Byte]()
While True
Try
If stream.DataAvailable Then
Dim bytes(client.ReceiveBufferSize) As Byte
stream.Read(bytes, 0, CInt(client.ReceiveBufferSize))
clientdata = Encoding.ASCII.GetString(bytes)
responsestring = "300$"
sendbytes = Encoding.ASCII.GetBytes(responsestring)
stream.Write(sendbytes, 0, sendbytes.Length)
End If
Threading.Thread.Sleep(25)
Catch ex As Exception
fehler = ex.Message
Exit While
End Try
End While
client.Close()
End If
Threading.Thread.Sleep(25)
End While


Hier der Java Code:

Java:
try {
	    clientSocket = new Socket(SERVER, 50000);
	    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
	    BufferedReader inFromServer = new BufferedReader(new              
                                                                  InputStreamReader(clientSocket.getInputStream()));
	
            while (true) 
		 {
		    Send = "200";
			     
		     outToServer.writeBytes(Send);
			     
		     while (!inFromServer.ready()) {}
		     Return = inFromServer.readLine();
			    
		    }		  	 	  
     } catch (UnknownHostException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }

Joa, freu mich von euch zu hören 🙂
 
ich wuerde so programmieren
Java:
public class Client extends thread {
...
public void run() {
      try {
           send = "200";
           StringBuffer buf = new StringBuffer();
           Socket client = new Socket(SERVER, 50000);
           InputStream in = client.getInputStream();
           OutputStream out = client.getOutputStream();
           out.write(send);
           while ((int b = in.read()) != -1) buf.append((char)b);
           in.close();
           out.close();
           client.close();
           return buf.toString();
      } catch (Exception e) {
           e.printStackTrace();
      }
      return null;
}
Sorry for my German.
 
Kann schon sein das es daran liegt das du Zeilenweise lesen willst aber nicht Zeileweise schreibst.
Versuche im Server mal folgendes :

"300\n$"

(oder wie auch immer man Escape-Sequenzen in VB schreibt)
Dadurch sendest du einen expliziten Zeilenumbruch mit.
Gibt es denn in VB nicht die möglichkeit auch Zeilenweise zu schreiben ? (Wobei Windows eh \r\n schicken würde.)
 
Danke für eure Antworten.

Ich habe auf der Serverseite mal einfach etwas hinzugefügt und auf der Clientseite die
andere Variante genommen:


sendbytes = Encoding.ASCII.GetBytes(responsestring + "\n$")
Stream.Write(sendbytes,0,sendbytes.length)

Java:
int b;
			     while (( b = inFromServer.read()) != -1) buf.append((char)b);


Habe es ebenfalls auch mit \n ausprobiert. Leider erhalte ich auf Clientseite dann einfach den Text mit "\n" am Ende. Oder müsste ich das mit ASCII am Ende hinzufügen? Nur da ich Erst seitdem ich Java
nutze auch Probleme habe, wollte ich mal hier bleiben.
 
Es ging darum das du die Esacpe-Sequenz "\n" sendest. Oder binär : 0x0A. Und nicht den Text-String "\n".
 
Achso, jo Danke, allerdings bin ich dann jetzt überfragt wie es geht.
Gehört zwar nicht hier ins Forum dann, aber, wie mache ich das?
Kannst du mir da weiterhelfen?
 
Ich zitiere mich mal selbst :

"(oder wie auch immer man Escape-Sequenzen in VB schreibt)"

Da ich kein VB kann weis ich auch nicht wie man dort Escape-Sequenzen schreibt. In Java schreibt man einfach \n , \r , \t , usw ... oder wenn man aus der ASCII-Tabelle den Byte-Wert kennt einfach 0x0A , 0x0D , usw ... Eigentlich gehören Escape-Sequenzen zu den wichtigen Grundlagen.
Was auch sein könnte ist das \0 oder 0x00 am Ende fehlt ... bin der Meinung mal sowas gelesen zu haben das C *und Java ist ja in C/C++ geschrieben , also die VM* halt \0 am String-Ende erwartet ...

Allgemein wäre es wirklich einfacher wenn du mal rausbekommen könntest ob und wie man in VB halt Zeichenweise senden *also das gegenstück zu Java : PrintStream.println(String)*.
 
Morgen zusammen 🙂

Vielen Dank für Eure Hilfe, jetzt hab ich eine Lösung die funktioniert.

Mein Server sendet scheinbar nach jedem Senden ein Abschlussbyte (Als Integer = 16).

Dann lese ich bei meinem Client die Schnittstelle solange aus, bis eben dieses Byte gelesen wird,
etwa so wie folgt:

Java:
int Readint = 0;
String Readletter = "";
String Readline = "";
StringBuffer buf = new StringBuffer();
while (Readint != 16)
{	
     Readint = inFromServer.read();
     if (Readint !=16)
        {
        buf.append((char)Readint);
        Readletter = buf.toString();
        Readline = Readline + Readletter;
        buf.delete(0, buf.length());
        }
 }
 
Dir ist schon bewusst das ASCII 16 = 0x0A = "\n" ist oder ? Und das sollte BufferedReader.readLine() eigentlich auch als solches erkennen und damit erwartungsgemäß arbeiten. Warum es da aber Probleme gibt weis ich nicht da ich wie gesagt kein "VB" spreche.
 
Dir ist schon bewusst das ASCII 16 = 0x0A = "\n" ist oder ? Und das sollte BufferedReader.readLine() eigentlich auch als solches erkennen und damit erwartungsgemäß arbeiten. Warum es da aber Probleme gibt weis ich nicht da ich wie gesagt kein "VB" spreche.

Falsch! ASCII (dezimal) 16 entspricht 0x10 und ist zwar auch ein Steuerzeichen, hat jedoch nichts mit einem Zeilenende zu tun.


@Daniel_Schepers:
In VB gibt es die Konstanten vbLF (0x0A) und vbCRLF (0x0D0A),
die man an eine Zeichenkette hängen kann, um einen LineFeed, bzw. einen
Return-LineFeed zu markieren. Wobei ich in Deinem Fall zu letzterem tendieren
würde (also vbCRLF).


Dein Basic-Code könnte dann eventuell so funktionieren:

Code:
sendbytes = Encoding.ASCII.GetBytes(responsestring + vbCRLF)
Stream.Write(sendbytes,0,sendbytes.length)

Ich hoffe, dass hilft Dir weiter, auch wenn schon ein paar Tage vergangen sind.

Gruß,
ROlf
 
Tipp so nebenbei: Bei kurzen Nachrichten am Ende der Nachricht den Stream flushen... sonst kann es sein dass er die Nachricht nicht gleich sendet, sondern erstmal puffert und auf mehr Daten zu senden wartet.

Daneben gibt's noch den Nagle-Algorithmus. Den sollte man, wenn man nur wenige, aber kleine Datenhäppchen schickt die schnell ankommen sollen am besten abschalten. Wieso und warum: Wikipedia erklärt's dir.

- Alex
 

Zurück
Oben