Java 使用套接字在客户端和服务器之间进行通信
好的,这是今天早些时候修订的问题,我已经加入了代码来帮助解释这个问题。我正在从客户端向服务器发送两条消息。然后,服务器拾取消息并对其进行处理。服务器最终尝试将消息发送回客户机(请注意服务器代码“testmessage”),这就是我遇到的问题。要么我没有在客户端接收到消息,要么我从服务器端错误地发送了消息Java 使用套接字在客户端和服务器之间进行通信,java,android,sockets,Java,Android,Sockets,好的,这是今天早些时候修订的问题,我已经加入了代码来帮助解释这个问题。我正在从客户端向服务器发送两条消息。然后,服务器拾取消息并对其进行处理。服务器最终尝试将消息发送回客户机(请注意服务器代码“testmessage”),这就是我遇到的问题。要么我没有在客户端接收到消息,要么我从服务器端错误地发送了消息 public class ClientConnection { String address, language, message; int portNumber; Socket client
public class ClientConnection {
String address, language, message;
int portNumber;
Socket clientSocket = null;
public ClientConnection(String lan, String mes, String add, int pn) throws IOException{
address = add;
portNumber = pn;
language = lan;
message = mes;
}
public String createAndSend() throws IOException{
// Create and connect the socket
Socket clientSocket = null;
clientSocket = new Socket(address, portNumber);
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
// Send first message - Message is being correctly received
pw.write(language+"\n");
pw.flush();
// Send off the data
// Send the second message - Message is being correctly received
pw.write(message);
pw.flush();
pw.close();
// Send off the data
// NOTE: Either I am not receiving the message correctly or I am not sending it from the server properly.
String translatedMessage = br.readLine();
br.close();
//Log.d("application_name",translatedMessage); Trying to check the contents begin returned from the server.
return translatedMessage;
}
服务器代码:
public class ServerConnection {
public static void main(String[] args) throws Exception {
// Delete - Using while loop to keep connection open permanently.
boolean status = false;
while( !status){
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(4444);
} catch (IOException e) {
System.err.println("Could not listen on port: 4444.");
System.exit(1);
}
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
} catch (IOException e) {
System.err.println("Accept failed.");
System.exit(1);
}
// Delete - Working as of here, connection is established and program runs awaiting connection on 4444
BufferedReader br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String language = br.readLine();
String message = br.readLine();
// Test - Works
System.out.println(language);
// Test - Works
System.out.println(message);
// Delete - Working as of here, both messages are passed and applied. Messages are received as sent from client.
TranslateMessage tm = new TranslateMessage();
String translatedMessage = tm.translateMessage(language, message);
// NOTE: This seems to be where I am going wrong, either I am not sending the message correctly or I am not receiving it correctly..
// PrintWriter writer = new PrintWriter(new BufferedOutputStream(clientSocket.getOutputStream()));
PrintWriter pw = new PrintWriter(clientSocket.getOutputStream(),true);
// Send translation back
System.out.println(translatedMessage);
// pw.write(translatedMessage+"\n");
pw.write("Return test"); // Test message!
pw.flush();
// Send off the data
pw.close();
br.close();
clientSocket.close();
serverSocket.close();
}
}
}
代码有点混乱,我可以看到一些重复的代码,我已经在我感觉到问题的地方发表了评论
谢谢你的帮助 您正在使用BufferedReader.readLine()从服务器读取响应,但在测试用例中,您发送的字符串未以\n或\r\n结尾,因此它将无法从文档中获取该行
public String readLine()
throws IOException
Read a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns:
A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached
另一项建议
在编写这样的请求-响应协议时,我不会依赖于行结尾来终止请求或响应。通常我会使用完全格式化的JSON字符串,或者我更喜欢二进制协议,其中所有请求和响应都以二进制计数(通常为4字节bigendian/网络字节顺序)作为前缀。然后客户端和服务器读取4个字节,然后读取后面的字节数。这可以处理通常在网络连接上发生的数据包碎片,还有助于避免恶意用户发送永远不会终止的长字符串进行DOS攻击
在Java中,可以使用ByteBuffer.order()来处理bigendian数 嗨,Jim,谢谢你的评论,如果你看上面,我正在使用发送一个变量,\n但是它也不起作用。哦,我看到你在客户端执行readline之前关闭printwriter,这可能不好,因为他们使用的是同一个套接字。我尝试移动pw.close,我运行的android应用程序冻结了。hmmmmDid如果您在发送的测试字符串中添加一个
\n
,它将冻结等待读取整个字符串到\n。此外,我认为没有必要关闭printwriter或bufferedreader。如果您只关闭套接字,我认为这些将被关闭。客户端中的readline返回了什么?它是空的吗?不,它是一个字符串,尽管在本例中它应该是从服务器发送的“字符串测试”。我仍然会在pw.write(“Return test”)
上粘贴一个\n,只是为了消除它作为一个问题。我做了Jim,但仍然没有用。也许新的一天会产生更好的结果。