簡體   English   中英

Java客戶端和C ++服務器通過TCP套接字發送和接收

[英]Java client and a C++ server send and receive via TCP Socket

我有一個C ++服務器和兩個客戶端(紅寶石和Java)。 一切都在64位linux機器(java 1.7.0_17)上運行。ruby客戶端可以正常工作,但是java版本會出現問題。

在Java中,我嘗試將字符串從客戶端發送到服務器。 實際上,服務器收到了整個字符串,但是服務器認為還有更多東西要接收。

紅寶石客戶端看起來像這樣:

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

這里的一切工作正常。 紅寶石客戶端發送一個字符串。 服務器接收該字符串並發送答復。

Java版本如下所示:

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();

另一方面,有一台C ++服務器:

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;
}

Java消息的服務器輸出是:

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

然后什么也沒有發生。 問題是:

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

陷入無限循環(或類似的循環)中。 如果我殺死了Java客戶端進程,或者輸入了類似的內容:

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

服務器端的輸出是:

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

此輸出是正確的(“發送答復成功”除外),但是在添加的情況下:

out.close();

客戶端無法收到服務器的回復。 因為套接字是關閉的。

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)

編輯

我試圖調用pw.flush(); 和不同的定界符,例如“ \\ n”,“ \\ r”,“ \\ r \\ n”和“ \\ n \\ r”,但是服務器仍然認為仍然有一些需要閱讀的內容。 我也嘗試使用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);

但是服務器無法接受該數據包。

ruby-client做類似socket.shutdownOutput();的事情。 (紅寶石:socket.shutdown 1)在看跌期權調用之后。 我更改了java-client-code:

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

而且有效!

正如@Charly所說:我必須定義一個“協議”。 就我而言,不允許更改任何與通信相關的代碼(在服務器和ruby客戶端中),因為另一組研究人員使用了此功能。 所以我修改這樣我的Java客戶端,它不完全一樣東西在准確的同時紅寶石客戶端(如協議的東西)。

僅通過調用println或printf來刷新PrintWriter緩沖區(當true為true時)。 調用print可能不會刷新緩沖區( Javadoc )。 嘗試調用println或直接使用OutputStreamWriter和flush()。 請注意使用正確的字符集(可以在OutputStreamWriter構造函數中進行設置)。

關閉流,分別以如下方式沖洗它:

DataOutputStream dataOut = new DataOutputStream(socket.getOutputStream());
dataOut.writeUTF(s);
dataOut.flush();
while ((recv_count = recv(SocketFD, buffer, sizeof(buffer) - 1, 0)) > 0) {
      if (recv_count == -1) {

我不知道您的問題是什么,但是這段代碼肯定是胡說八道。 內部測試不可能成功。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM