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
Du musst angemeldet sein, um einen Kommentar abzugeben.
PrintWriter Puffer (wenn autoflush ist true), wird nur geleert, durch den Aufruf println oder printf. Aufruf drucken, möglicherweise nicht der Puffer geleert (Javadoc). Versuchen Sie den Aufruf println oder verwenden Sie einen OutputStreamWriter direkt und flush().
Bewusst sein mit dem richtigen charset (Sie können es im Konstruktor von OutputStreamWriter).
Ich habe die java-client-source
Ich weiß wirklich nicht c++, aber sollte nicht Sie haben irgendeine Art von Trennzeichen an das Ende der Nachricht an den server ? So wie ich das sehe, ist dein server nur senden der echo-wenn die Verbindung geschlossen ist... Zum Beispiel die readLine() BufferedReader in Java erst wieder beim Lesen ein \n oder ein \r ist.
Ich' habe bereits versucht, so etwas wie: "Hallo, Welt!\n" aber der server gibt alle raus und hängt an der gleichen Leitung. Wie ich schon erwähnt, am Ende von meinem post, ich glaube, ich brauche ein spezielles Trennzeichen, aber warum funktioniert das in ruby? Und natürlich weiß ich nicht was zu schreiben, der server-code je nach Programmiersprache, die der client verwendet.
Natürlich können Sie nicht schreiben Sie einen server, basierend auf der Programmiersprache, die der client verwendet. Beide müssen kompatibel sein, das ist, warum Sie benötigen, um zu definieren, eine Art "Protokoll" zwischen den beiden. Wenn Sie entscheiden, dass muss der client sendet einen String, und "\n", das ist, wie es ist und machen Sie das gleiche in Ruby und Java. In Ihrem c++ - code, testen Sie einfach, Wann immer Sie dieses symbol wird angezeigt, und Sie können Ihre Schleife und sende die Antwort. Über die Ruby, ich weiß wirklich nicht, aber es scheint, dass die "macht" schreiben Sie ein newline-Sequenz am Ende.
InformationsquelleAutor Charly
Den stream schließen jeweils bündig in einer Weise wie dieser:
InformationsquelleAutor Jan Piel
Ich weiß nicht, was dein problem ist, aber dieser code ist sicherlich Unsinn. Es ist unmöglich, die innere test jemals erfolgreich zu sein.
Ich habe die C++ server code
InformationsquelleAutor user207421