A R*_*A R 24 java network-programming inputstream serversocket bufferedinputstream
我在我的一个项目中使用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();
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢.
rod*_*olk 50
您遇到的问题与TCP流性质有关.
您从服务器发送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)
{
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();
}
Run Code Online (Sandbox Code Playgroud)
现在,通常预先知道一个节点(此处的服务器)发送的数据大小.然后,您需要为服务器与TCP通信的客户端(或任何两个节点)之间的通信定义自己的小协议.
最常见也很简单的是定义TLV:Type,Length,Value.因此,您定义从服务器发送到客户端的每条消息都带有:
因此,您知道必须至少接收2个字节,而使用第二个字节,您知道需要读取多少个字节.
这只是一个可能的协议的建议.你也可以摆脱"类型".
所以它会是这样的:
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();
}
Run Code Online (Sandbox Code Playgroud)
以下代码编译并且看起来更好.假设提供长度的前两个字节以二进制格式到达,在网络结束(big endian)中.不关注消息其余部分的不同编码类型.
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();
}
}
}
Run Code Online (Sandbox Code Playgroud)