如何读取服务器套接字JAVA中的所有InputStream
我在我的项目之一使用Java.net。 我写了一个从客户端获取inputStream的App Server。 但有时候,我的(缓冲的)InputStream无法获得客户端发送给我的服务器的所有OutputStream。 我怎么能写一个等待或这样的事情,我的InputStream获取客户端的所有OutputStream?
(我的InputStream不是一个string)
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(); } }
谢谢。
您遇到的问题与TCPstream媒体性质有关。
从服务器发送100字节(例如)的事实并不意味着您将在第一次阅读客户端时读取100字节。 也许从服务器发送的字节到达多个TCP段到客户端。
你需要实现一个你阅读的循环,直到收到整个消息。 让我用DataInputStream
而不是BufferedinputStream
提供一个例子。 非常简单的东西给你一个例子。
假设您事先知道服务器要发送100字节的数据。
在客户端你需要写:
byte[] messageByte = new byte[1000]; boolean end = false; String dataString = ""; try { DataInputStream in = new DataInputStream(clientSocket.getInputStream()); while(!end) { bytesRead = in.read(messageByte); messageString += new String(messageByte, 0, bytesRead); if (messageString.length == 100) { end = true; } } System.out.println("MESSAGE: " + messageString); } catch (Exception e) { e.printStackTrace(); }
现在,一个节点(这里的服务器)发送的数据大小通常是事先不知道的。 然后,您需要定义您自己的小型协议,用于与TCP进行通信的服务器和客户端(或任何两个节点)之间的通信。
最常见和最简单的是定义TLV:types,长度,值。 所以你定义从服务器发送到客户端的每条消息都附带了:
- 1字节指示types(例如,它也可以是2或其他)。
- 1字节(或其他)的消息长度
- N字节的值(N表示长度)。
所以你知道你必须得到至less2字节,第二个字节,你知道有多less个字节,你需要阅读。
这只是一个可能的协议的build议。 你也可以摆脱“types”。
所以它会是这样的:
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); messageString += new String(messageByte, 0, bytesRead); if (messageString.length == bytesToRead ) { end = true; } } System.out.println("MESSAGE: " + messageString); } catch (Exception e) { e.printStackTrace(); }
下面的代码编译和看起来更好。 它假定前两个字节提供长度以二进制格式,在networkingendianship(big endian)中。 没有把重点放在消息其他部分的不同编码types上。
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 messageString = ""; 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); messageString += new String(messageByte, 0, bytesRead); if (messageString.length() == bytesToRead ) { end = true; } } //All the code in the loop can be replaced by these two lines //in.readFully(messageByte, 0, bytesToRead); //messageString = new String(messageByte, 0, bytesToRead); System.out.println("MESSAGE: " + messageString); } catch (Exception e) { e.printStackTrace(); } } }
你可以像这样读取你的BufferedInputStream。 它将读取数据,直到达到以-1表示的数据stream结束。
inputS = new BufferedInputStream(inBS); byte[] buffer = new byte[1024]; //If you handle larger data use a bigger buffer size int read; while((read = inputS.read(buffer)) != -1) { System.out.println(read); // Your code to handle the data }