2012-03-28 1 views
4

ich eine Socket-Kommunikation zwischen meinen eigenen geschrieben java Server und C# Client benötigen, ist das Problem, dass die C# Client keine Nachrichten von meinem Java-Server nicht empfangen können, aber Nachrichten an mein Java Senden Server funktioniert.Java <-> # Sockel C: kippen Nachrichten empfangen

mein Workflow:

  1. Java: Erstellen Server
  2. Java: Warten auf Client-Verbindung
  3. C#: Erstellen Sie Client-
  4. C#: a senden: Verbindung zum Server
  5. C# Bauen msg zum Server
  6. Java: msg empfangen
  7. java: senden Sie die Nachricht an C# client
  8. C#: empfangen von msg vom Server < - das ist der Punkt, wo der Client auf eine Nachricht wartet, aber nie bekommen.

Java Server Code:

public class Communicator { 

    private int m_port; 
    private Socket m_socket; 
    private ServerSocket m_serverSocket; 

    public Communicator(int port) { 
     this.m_port = port; 
     initConnection(); 
    } 

    private void initConnection() { 

     try { 
      System.out.println("Creating Server"); 
      m_serverSocket = new ServerSocket(m_port); 
      System.out.println("Waiting for client connection"); 
      m_socket = m_serverSocket.accept(); 
      System.out.println("Connection made"); 

     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public String sendMsg(JSONMessage msg) { 
     try { 

    //get msg 
    BufferedReader bufferedReader = new BufferedReader(
      new InputStreamReader(m_socket.getInputStream())); 
    System.out.println("Waiting for msg..."); 
     String answer = bufferedReader.readLine(); 
     System.out.println("Received: " + answer); 

     //send msg 
     PrintWriter writer = new PrintWriter(m_socket.getOutputStream(),true); 
     writer.print(msg.getMsg()); 
     System.out.println("Sending: " + msg.getMsg()); 

     writer.flush(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

     return ""; 
    } 

} 

Mein C# Client-Code:

class Communicator 
    { 
     private int m_port; 
     private Thread mainThread; 

     public Communicator(int port) 
     { 
      m_port = port; 
      mainThread = new Thread(new ThreadStart(this.initConnection)); 
      mainThread.Start(); 
     } 

     public void initConnection() 
     { 
      IPEndPoint ip = new IPEndPoint(IPAddress.Parse("127.0.0.1"), m_port); 
      Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

      try 
      { 
       Console.WriteLine("Trying to build connection"); 
       server.Connect(ip); 
       Console.WriteLine("Connection successful"); 

       NetworkStream ns = new NetworkStream(server); 
       StreamReader sr = new StreamReader(ns); 
       StreamWriter sw = new StreamWriter(ns); 
       string data; 

       string welcome = "Hello"; 
       Console.WriteLine("Sending: " + welcome); 
       sw.WriteLine(welcome); 
       sw.Flush(); 

       Console.WriteLine("Receiving..."); 
       data = sr.ReadLine(); 
       // --> NEVER REACHING THIS POINT <--- 
       Console.WriteLine("Received: " + data);           

      } 
      catch (SocketException e) 
      { 
       Console.WriteLine("Connection failed."); 
       return; 
      } 

     } 
    } 

Hat jemand eine Ahnung hat, warum es nie Console.WriteLine("Received: " + data); meinen Client-Code erreicht?

Ich versuchte bereits mit Wartezeiten auf beiden Seiten. Ich bekomme keine Ausnahmen oder Fehler, daher habe ich keine Ahnung, wo mein Problem ist.

Dank

Antwort

2

Sie müssen println() verwenden, das eine neue Zeile anstelle von print() hinzufügt. In Java wartet readLine auf eine neue Zeile und ich würde erwarten, dass es in C# dasselbe tut. Auch println wird automatisch gespült, so dass Sie auch nicht spülen müssen.

Wenn Sie diese Verbindung mreo nur einmal verwenden möchten, müssen Sie den BufferedReader und PrintWriter für die Verbindung beibehalten. (Ich schlage vor, dass Sie diese erstellen, nachdem der Socket erstellt/akzeptiert wurde). Das mehrfache Erstellen für denselben Socket kann fehleranfällig und verwirrend sein.

4

Wenn Ihr Receiver Linien erwarten, hat Ihr Sender Linien zu senden. Ihr Absender sendet keine Leitungen, so dass der Empfänger für immer wartet, bis er einen bekommt.

Um diese Art von Problemen in Zukunft zu vermeiden, sollten Sie immer ein Spezifikationsdokument erstellen, das erklärt, wie Ihr Protokoll funktioniert, idealerweise auf Byte-Ebene. Es sollte angeben, ob das Protokoll Nachrichten enthält und wenn ja, wie der Absender Nachrichtengrenzen markiert und wie der Empfänger sie identifiziert.

Hier identifiziert Ihr Empfänger Nachrichtengrenzen, indem er nach Zeilenenden sucht. Ihr Absender markiert jedoch keine Nachrichtengrenzen mit Zeilenenden. Also wartet der Empfänger für immer.

Wenn Sie eine Protokollspezifikation hätten, wäre dies offensichtlich gewesen. In der Zukunft fordere ich Sie dringend auf, die Zeit zu investieren, um jedes von Ihnen implementierte Protokoll festzulegen.

+0

Wechseln Sie zu writer.println (msg.getMsg()); oder benutze sr.Read nicht ReadLine in C#. – weismat

+0

Wenn er 'sr.Read' verwendet, hat er keine Möglichkeit, Nachrichtengrenzen zu identifizieren. Das könnte oder könnte nicht wichtig sein, je nachdem, was er macht. –

+0

Wenn der Java-Server auch Java-Clients hat, muss er den C# -Client ändern, nicht den Java-Server. Mit JSON sollte es recht einfach sein zu bestimmen, ob es sich um eine gültige JSON-Nachricht handelt oder nicht. – weismat