TCP/IP 客户端:从服务器读取多个输入流的最佳方式
TCP/IP Client : best way to read multiple inputstreams from server
我正在创建一个 java 客户端程序,它向服务器发送命令,然后服务器发回确认和响应字符串。
The response is sent back in this manner
client -> server : cmd_string
server -> client : ack_msg(06)
server -> client : response_msg
当我尝试读取输入时,我只能通过一个输入流读取确认消息
我的客户端程序能够以某种方式读取消息(hacky 方法)。要读取输入,我必须使用 Bufferedreader.
读取确认消息
- 这缓冲 reader 只能读取 ack_msg 而不是以下消息
- 读取响应消息需要 DataInputstream 代码。
- 如果我跳过第 1 步而只使用 Datainputstream,我将无法读取完整的消息。
Client.java
try {
Socket clientSocket = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);// ip,port
System.out.println(" client Socket created .. ");
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
String ToServer = command;
outToServer.println(ToServer);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//
// while (!in.ready()) {
// }
System.out.println(in.read()); // Read one line and output it
// ===
byte[] messageByte = new byte[1000];//assuming msg size -need to know eact msg size ?
boolean end = false;
String dataString = "";
int bytesRead = 0;
try {
DataInputStream in1 = new DataInputStream(clientSocket.getInputStream());
//
while (!end) {
bytesRead = in1.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length() > 0) {
end = true;
}
}
System.out.println("MESSAGE: " + dataString);
} catch (Exception e) {
e.printStackTrace();
}
// ===
in.close();
clientSocket.close();
System.out.print("connection closed");
} catch (Exception e) {
System.out.print("Whoops! It didn't work!\n");
e.printStackTrace();
}
输出
客户端套接字已创建..
响应:6
消息:³CO³0³Œ
连接关闭
当我跳过第 1 步时
客户端套接字已创建..
留言:-
连接关闭
How can I write code that reads all the input from
server(acknowledgement msg & response message & it should also check
the size of data and read accordingly)?
参考How to read all of Inputstream in Server Socket JAVA
谢谢
这些语句强制在发送至少 1 个字节后立即关闭流。
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length() > 0) {
end = true;
}
一旦收到 6 的确认,连接就会关闭。如果忽略ack,响应可能会在多个数据包中发送,连接将在收到第一个数据包后关闭。
您必须能够确定 ack 和响应何时结束。
- 如果你知道ack和response中有多少个字符,你可以像你提到的问题一样循环。您将需要一个用于确认的循环和一个用于响应的循环。
- 如果你不知道人数
字符,那么你将不得不寻找特殊字符,比如
end-of-line 或 end-of-file 知道 ack 行何时结束以及何时结束
服务器响应结束。寻找每条消息结尾的特殊字符。
第三种可能是等待
具体时间。时间到了,继续。这在 TCP 上不可靠,因为数据可能会丢失并重新发送。回复所需的时间可能比您分配的时间要长。 我同意下面的评论。本来,我犹豫要不要在列表中添加 3。此选项很可能用于检测通信通道的问题。如果时间到了,那么客户端就会报错放弃,不会继续处理,就好像一切正常一样。
您不能在同一个底层套接字上同时使用 BufferedReader 和 DataInputStream。您将丢失 BufferedReader 中的数据。对所有内容以及套接字的生命周期使用相同的流或 reader。同上编写器和输出流。
InputStream input = null;
OutputStream output = null;
Socket cs = new Socket("LocalHost", 6789);
input = cs.getInputStream();
output = cs.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(output));
bw.write("Send your String");
bw.flush();
int bytesRead = 0;
byte[] messageByte = new byte[1000];
String dataString = "";
bytesRead = input.read(messageByte);
dataString = new String(messageByte, 0, bytesRead);
我正在创建一个 java 客户端程序,它向服务器发送命令,然后服务器发回确认和响应字符串。
The response is sent back in this manner
client -> server : cmd_string
server -> client : ack_msg(06)
server -> client : response_msg
当我尝试读取输入时,我只能通过一个输入流读取确认消息
我的客户端程序能够以某种方式读取消息(hacky 方法)。要读取输入,我必须使用 Bufferedreader.
读取确认消息- 这缓冲 reader 只能读取 ack_msg 而不是以下消息
- 读取响应消息需要 DataInputstream 代码。
- 如果我跳过第 1 步而只使用 Datainputstream,我将无法读取完整的消息。
Client.java
try {
Socket clientSocket = new Socket(SERVER_ADDRESS, TCP_SERVER_PORT);// ip,port
System.out.println(" client Socket created .. ");
PrintWriter outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
String ToServer = command;
outToServer.println(ToServer);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
//
// while (!in.ready()) {
// }
System.out.println(in.read()); // Read one line and output it
// ===
byte[] messageByte = new byte[1000];//assuming msg size -need to know eact msg size ?
boolean end = false;
String dataString = "";
int bytesRead = 0;
try {
DataInputStream in1 = new DataInputStream(clientSocket.getInputStream());
//
while (!end) {
bytesRead = in1.read(messageByte);
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length() > 0) {
end = true;
}
}
System.out.println("MESSAGE: " + dataString);
} catch (Exception e) {
e.printStackTrace();
}
// ===
in.close();
clientSocket.close();
System.out.print("connection closed");
} catch (Exception e) {
System.out.print("Whoops! It didn't work!\n");
e.printStackTrace();
}
输出
客户端套接字已创建..
响应:6
消息:³CO³0³Œ
连接关闭
当我跳过第 1 步时
客户端套接字已创建..
留言:-
连接关闭
How can I write code that reads all the input from server(acknowledgement msg & response message & it should also check the size of data and read accordingly)?
参考How to read all of Inputstream in Server Socket JAVA
谢谢
这些语句强制在发送至少 1 个字节后立即关闭流。
dataString += new String(messageByte, 0, bytesRead);
if (dataString.length() > 0) {
end = true;
}
一旦收到 6 的确认,连接就会关闭。如果忽略ack,响应可能会在多个数据包中发送,连接将在收到第一个数据包后关闭。
您必须能够确定 ack 和响应何时结束。
- 如果你知道ack和response中有多少个字符,你可以像你提到的问题一样循环。您将需要一个用于确认的循环和一个用于响应的循环。
- 如果你不知道人数 字符,那么你将不得不寻找特殊字符,比如 end-of-line 或 end-of-file 知道 ack 行何时结束以及何时结束 服务器响应结束。寻找每条消息结尾的特殊字符。
第三种可能是等待 具体时间。时间到了,继续。这在 TCP 上不可靠,因为数据可能会丢失并重新发送。回复所需的时间可能比您分配的时间要长。我同意下面的评论。本来,我犹豫要不要在列表中添加 3。此选项很可能用于检测通信通道的问题。如果时间到了,那么客户端就会报错放弃,不会继续处理,就好像一切正常一样。
您不能在同一个底层套接字上同时使用 BufferedReader 和 DataInputStream。您将丢失 BufferedReader 中的数据。对所有内容以及套接字的生命周期使用相同的流或 reader。同上编写器和输出流。
InputStream input = null;
OutputStream output = null;
Socket cs = new Socket("LocalHost", 6789);
input = cs.getInputStream();
output = cs.getOutputStream();
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(output));
bw.write("Send your String");
bw.flush();
int bytesRead = 0;
byte[] messageByte = new byte[1000];
String dataString = "";
bytesRead = input.read(messageByte);
dataString = new String(messageByte, 0, bytesRead);