【发布时间】:2018-04-10 11:37:09
【问题描述】:
我正在使用 Commons-IO 从 Socket 读取和写入。一切正常,直到有效载荷大小达到最大值 1448/2896。
下面是代码sn-p。真的不知道怎么处理。 也检查了系统缓冲区大小
$ cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
public static void usingCommonsIO(){
Socket socket = null;
try {
socket = new Socket(serverIP, 55000);
IOUtils.write(request.getBytes(), socket.getOutputStream());
System.out.println("Message Sent....");
StringBuilder response = new StringBuilder();
String resp =IOUtils.toString(socket.getInputStream(), "UTF-8");
System.out.println(resp);
} catch (IOException e) {
e.printStackTrace();
}
}
另外尝试使用 DataInputStream 但没有运气。截取的代码如下。
public static void usingDataIOStream(String requestStr){
Socket socket = null;
try {
socket = new Socket("192.168.1.6", 55000);
System.out.println("Request Length -:" + request.length());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.write(requestStr.getBytes("UTF-8"), 0, requestStr.length());
out.flush();
System.out.println("Message Sent....");
DataInputStream din = new DataInputStream(socket.getInputStream());
byte[] response = new byte[16*1024];
int responseLength = din.read(response);
System.out.println("Response -:" + new java.lang.String(response, 0, responseLength));
} catch (IOException e) {
e.printStackTrace();
}
}
令人困惑的部分是相同的代码有时仅使用 1448 字节,有时最多使用 2896 字节。没有特定的模式。
更新 1
为了模拟它,我尝试自己编写服务器套接字,代码如下。注意到这一点的奇怪事情是,在第一次请求时,大小为 6500 的有效负载被正确读取和接收。从第二个请求开始连接重置。我在这里遗漏了什么吗?
public static void usingBAOS() throws IOException {
server = new ServerSocket(port);
Socket socket = null;
DataInputStream din = null;
DataOutputStream dos = null;
while (true) {
System.out.println("Waiting for Client...");
try {
// Accepting Client's connection
socket = server.accept();
System.out.println("Connnected to client " + socket.getInetAddress());
din = new DataInputStream(socket.getInputStream());
// Read request payload from Socket
String requestString = readRequest(din);
System.out.println("Request Read.....");
System.out.println("Writing Response.....");
// Writing response to socket
dos = writeResponse(socket, requestString);
} catch (IOException e) {
e.printStackTrace();
}finally {
//close resources
din.close();
System.out.println("InputStream is closed......");
dos.close();
System.out.println("OutputStream is closed......");
socket.close();
System.out.println("Socket is closed......");
}
}
}
private static DataOutputStream writeResponse(Socket socket, String requestString) throws IOException {
String responseString = "Hi Client" + requestString;
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//write object to Socket
dos.write(responseString.getBytes(),0, responseString.getBytes().length);
dos.flush();
return dos;
}
private static String readRequest(DataInputStream din) throws IOException {
byte[] response = new byte[16*1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int n = 0;
boolean read = true;
while(read){
n = din.read(response);
baos.write(response, 0, n);
if(baos.toString().length() == n){
read = false;
}
}
baos.flush();
String requestString = baos.toString();
return requestString;
}
【问题讨论】:
-
您使用
DataInputStream的代码是错误的。不能保证单个read(byte[])会读取所有数据。返回值表示读取了多少字节。 -
@Kayaman 感谢您的意见。试过但没有用。 ByteArrayOutputStream baos = new ByteArrayOutputStream();诠释 n = 0; while((n = din.read(response) )!= -1){ baos.write(response, 0, n); }
-
你的意思是你有同样的行为?会不会是服务器端的问题?你在其他电脑上试过吗?
-
是的,仍然是相同的行为。这是第三方服务。怀疑是服务器端的问题,但他们声称其他客户端能够消费而没有任何此类问题。
-
这个问题有两个问题:1)你正在实现一个协议,但你还没有为它提供一个规范。我们必须从您的代码中推断出协议,但这显然无助于诊断不正确的实现; 2)你从不说问题是什么。你暗示出了什么问题,但不知道那是什么。
标签: java sockets datainputstream apache-commons-io