我在我的项目之一中使用Java.net。我写了一个从客户端获取inputStream的App Server。但是有时我的(缓冲的)InputStream无法获得客户端发送到我的服务器的所有OutputStream。我该如何写一个等待或类似的东西,让我的InputStream获得客户端的所有OutputStream?
(我的InputStream不是字符串)
private Socket clientSocket; private ServerSocket server; private BufferedOutputStream outputS; private BufferedInputStream inputS; private InputStream inBS; private OutputStream outBS; server = new ServerSocket(30501, 100); clientSocket = server.accept(); public void getStreamFromClient() { try { outBS = clientSocket.getOutputStream(); outputS = new BufferedOutputStream( outBS); outputS.flush(); inBS = clientSocket.getInputStream(); inputS = new BufferedInputStream( inBS ); } catch (Exception e) { e.printStackTrace(); } }
谢谢。
例如,你从服务器发送了100字节的事实并不意味着你在第一次读取时将在客户端中读取100字节。从服务器发送的字节可能在几个TCP段中到达客户端。
你需要实现一个循环,在该循环中你将阅读直到收到整个消息为止。让我提供一个示例,以DataInputStream代替BufferedinputStream。举一个简单的例子。
DataInputStream
BufferedinputStream
假设你事先知道服务器要发送100字节的数据。
在客户端中,你需要编写:
byte[] messageByte = new byte[1000]; boolean end = false; String dataString = ""; try { DataInputStream in = new DataInputStream(clientSocket.getInputStream()); while(!end) { int bytesRead = in.read(messageByte); dataString += new String(messageByte, 0, bytesRead); if (dataString.length == 100) { end = true; } } System.out.println("MESSAGE: " + dataString); } catch (Exception e) { e.printStackTrace(); }
现在,通常一个节点(这里的服务器)发送的数据大小通常是未知的。然后,你需要定义自己的小型协议,用于与TCP进行通信的服务器和客户端(或任何两个节点)之间的通信。
这只是可能协议的建议。你也可以摆脱“类型”。
因此,它将类似于:
byte[] messageByte = new byte[1000]; boolean end = false; String dataString = ""; try { DataInputStream in = new DataInputStream(clientSocket.getInputStream()); int bytesRead = 0; messageByte[0] = in.readByte(); messageByte[1] = in.readByte(); int bytesToRead = messageByte[1]; while(!end) { bytesRead = in.read(messageByte); dataString += new String(messageByte, 0, bytesRead); if (dataString.length == bytesToRead ) { end = true; } } System.out.println("MESSAGE: " + dataString); } catch (Exception e) { e.printStackTrace(); }
以下代码可以编译并看起来更好。假定提供长度的前两个字节以网络格式(大字节序)以二进制格式到达。对于邮件的其余部分,不关注不同的编码类型。
import java.nio.ByteBuffer; import java.io.DataInputStream; import java.net.ServerSocket; import java.net.Socket; class Test { public static void main(String[] args) { byte[] messageByte = new byte[1000]; boolean end = false; String dataString = ""; try { Socket clientSocket; ServerSocket server; server = new ServerSocket(30501, 100); clientSocket = server.accept(); DataInputStream in = new DataInputStream(clientSocket.getInputStream()); int bytesRead = 0; messageByte[0] = in.readByte(); messageByte[1] = in.readByte(); ByteBuffer byteBuffer = ByteBuffer.wrap(messageByte, 0, 2); int bytesToRead = byteBuffer.getShort(); System.out.println("About to read " + bytesToRead + " octets"); //The following code shows in detail how to read from a TCP socket while(!end) { bytesRead = in.read(messageByte); dataString += new String(messageByte, 0, bytesRead); if (dataString.length() == bytesToRead ) { end = true; } } //All the code in the loop can be replaced by these two lines //in.readFully(messageByte, 0, bytesToRead); //dataString = new String(messageByte, 0, bytesToRead); System.out.println("MESSAGE: " + dataString); } catch (Exception e) { e.printStackTrace(); } } }