Java-client und C++ server senden und empfangen über TCP-Socket

Ich habe ein C++ - server und zwei clients (ruby und java).
Läuft alles auf einem 64-bit-linux-Maschine (java 1.7.0_17)
Die ruby-client ist voll funktionsfähig, aber die java-version Probleme macht.

In Java habe ich versucht zu senden eine Zeichenfolge, die vom client an den server. Eigentlich ist der Server erhielt den gesamten String, aber der server denkt, es ist noch etwas mehr zu erhalten.

Die ruby-client sieht ein wenig wie diese:

socket = TCPSocket.open(@options[:host],@options[:port])
test = "Hello, World"
socket.puts test
socket.shutdown 1
response = socket.gets

Alles hier ist in Ordnung. Die ruby-client sendet einen string. Der server empfängt diesen string und sendet eine Antwort.

Die Java-Version sieht so aus:

String ip = "127.0.0.1";
int port = 6686;
java.net.Socket socket = new java.net.Socket(ip,port);
OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream());
InputStreamReader in = new InputStreamReader(socket.getInputStream());

String msg = "Hello, world!";

//send
PrintWriter pw = new PrintWriter(out, true);
pw.print(msg);
pw.flush();
//I also tried: out.write(msg); out.flush(); nothing changed

//receive the reply
BufferedReader br = new BufferedReader(in);
char[] buffer = new char[300];
int count = br.read(buffer, 0, 300);
String reply = new String(buffer, 0, count);
System.out.println(reply);

socket.close();

Auf der anderen Seite gibt es einen C++ - Server:

string receive(int SocketFD) {
   char buffer[SOCKET_BUFFER_SIZE];
   int recv_count;

   //empty messagestring
   string message = "";

   //empty buffer
   memset(buffer, 0, sizeof(buffer));

   while ((recv_count = recv(SocketFD, buffer, sizeof(buffer) - 1, 0)) > 0) {
      /*if (recv_count == -1) {
         cout << "failed." << endl;
         break;
      }*/
      cout << recv_count << endl;
      if (ECHO_SOCKETS) cout << "received: " << buffer << endl;

      message.append(buffer);
      memset(buffer, 0, sizeof(buffer));

      if (ECHO_SOCKETS) cout << "message is now: " << message << endl;

   }
   return message;
}

Die server-Ausgabe von Java-Meldung:

13
received: Hello, world!
message is now: Hello, world!

und dann passiert nichts.
Das problem ist, dass:

recv(SocketFD, buffer, sizeof(buffer) - 1, 0)

ist gefangen in einer endlos-Schleife (oder so ähnlich).
Wenn kill ich die Java-client-Prozess oder ich etwas wie:

pw.print(msg);
out.close();

den Ausgang auf der server-Seite ist:

_sending reply: "Request unrecognized/invalid" request="Hello, world!"
send reply success
now close connection

Dieser Ausgang ist rechts (außer "Antwort senden Erfolg"), aber im Fall von hinzufügen:

out.close();

kann der client keine Antwort vom server. Da der Socket geschlossen.

java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:864)
at MyServer.writeMessage(MyServer.java:56)
at MyServer.test(MyServer.java:42)
at MyServer.main(MyServer.java:30)

Bearbeiten

Ich versuchte zu rufen, pw.flush(); und verschiedene Trennzeichen wie "\n", "\r", "\r\n" und "\n\r", aber der server immer noch denkt, dass es noch etwas zu Lesen. Ich habe auch versucht zu verwenden DatagramSockets:

java.net.DatagramSocket dSocket = new java.net.DatagramSocket();
InetAddress address = InetAddress.getByName("localhost");
String msg = "Hello, world!";
byte[] buf = msg.getBytes();
java.net.DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 6686);

Aber der server nicht akzeptieren können das Paket.

Lösung

Die ruby-client hat so etwas wie eine Steckdose.shutdownOutput(); (ruby: socket.shutdown-Funktion 1) nach dem Aufruf von puts. Ich habe die java-client-code:

out.write(msg);
socket.shutdownOutput();

- und es funktioniert!

Wie @Charly sagte: ich habe eine Definition "Protokoll". In meinem Fall bin ich nicht verändern darf, jegliche Kommunikation im Zusammenhang mit code (in der server und die ruby-client), weil diese Funktion wird von einer anderen Gruppe von Forschern. Also ich habe ändern mein java-client so, dass es nicht die genaue gleichen Dinge auf die genaue gleichen Zeit wie die ruby-client (sowas wie ein Protokoll).

InformationsquelleAutor MartinO. | 2013-04-09

Schreibe einen Kommentar