Mar*_*nO. 6 c++ ruby java sockets send
我有一个C++服务器和两个客户端(ruby和java).一切都在64位Linux机器上运行(java 1.7.0_17)ruby客户端完全正常工作,但java版本存在问题.
在Java中,我试图从客户端向服务器发送一个String.实际上,服务器收到了整个字符串,但服务器认为还有更多要接收的内容.
ruby客户端看起来有点像这样:
socket = TCPSocket.open(@options[:host],@options[:port])
test = "Hello, World"
socket.puts test
socket.shutdown 1
response = socket.gets
Run Code Online (Sandbox Code Playgroud)
这里的一切都很好.ruby客户端发送一个字符串.服务器接收该字符串并发送回复.
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();
Run Code Online (Sandbox Code Playgroud)
另一方面有一个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;
}
Run Code Online (Sandbox Code Playgroud)
Java消息的服务器输出是:
13
received: Hello, world!
message is now: Hello, world!
Run Code Online (Sandbox Code Playgroud)
然后没有任何反应.问题是:
recv(SocketFD, buffer, sizeof(buffer) - 1, 0)
Run Code Online (Sandbox Code Playgroud)
陷入无尽的循环(或类似的东西).如果我终止了Java客户端进程,或者输入了类似的内容:
pw.print(msg);
out.close();
Run Code Online (Sandbox Code Playgroud)
服务器端的输出是:
_sending reply: "Request unrecognized/invalid" request="Hello, world!"
send reply success
now close connection
Run Code Online (Sandbox Code Playgroud)
此输出正确("发送回复成功"除外),但在添加时:
out.close();
Run Code Online (Sandbox Code Playgroud)
客户端无法接收服务器的回复.因为Socket已关闭.
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)
Run Code Online (Sandbox Code Playgroud)
我试着打电话给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);
Run Code Online (Sandbox Code Playgroud)
但是服务器无法接受数据包.
ruby-client执行类似socket.shutdownOutput(); (ruby:socket.shutdown 1)在调用puts之后.我改变了java-client-code:
out.write(msg);
socket.shutdownOutput();
Run Code Online (Sandbox Code Playgroud)
它的工作原理!
正如@Charly所说:我必须定义一个"协议".在我的情况下,我不允许更改任何与通信相关的代码(在服务器和ruby-client中),因为此功能由另一组研究人员使用.所以我修改这样我的Java客户端,它确实的确切同样的事情在精确的同时红宝石客户端(如协议的东西).
| 归档时间: |
|
| 查看次数: |
11475 次 |
| 最近记录: |