将 java.net.Socket.getInputStream() 转换为 byte[] 显示大延迟
Converting java.net.Socket.getInputStream() to byte[] showing large delay
我设计了一个 Java 客户端 class,它需要通过套接字将字节 [] 数组发送到 Java 服务器 class。这是我的代码:
ByteArrayClient.java
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ByteArrayClient {
public static void main(String[] args) {
//make POJO__________________________
ByteEncodeSubscriptionReq sr1=ByteEncodeSubscriptionReq.makeRequest(103, "Str1", "Str2");
//Connection details____________________
String serverName = "localhost";
int port = 6060;
try {
//Establish Connection with server_______________________________
System.out.println("ByteArrayClient: Connecting to " + serverName +":" + port+"...");
Socket client = new Socket(serverName, port);//make new socket
System.out.println("ByteArrayClient: connected to " + client.getRemoteSocketAddress());
//Encode POJO to ByteArray________________________________
byte[] SubscripReqByteArray=ByteEncodeSubscriptionReq.encode(sr1);
//encoded correctly to a 44 bit byte array
System.out.println("ByteArrayClient: SubscripTionRequest successfully encoded");
//Send POJO ByteArray to server__________________________
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.write(SubscripReqByteArray);;
System.out.println("ByteArrayClient: POJO sent to server");
//Receive Server response_________________________________
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("ByteArrayClient received: " + in.readUTF());
//close socket____________________________________
client.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("PojoClient: Connection Failed");
}
}
}
...和ByteArrayServer.java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class ByteArrayServer extends Thread{
private ServerSocket serverSocket;
public ByteArrayServer(int port) throws IOException {
serverSocket = new ServerSocket(port);//create server socket
serverSocket.setSoTimeout(15000);//socket closes after 15 seconds
this.start();
}
public void run() {
while (true) {//server runs infinitely______________
try {
System.out.println("ByteArrayServer: Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket servedClient = serverSocket.accept();//client socket
System.out.println("ByteArrayServer: connected to " + servedClient.getRemoteSocketAddress());
//Receive Client ByteArray___________________________________________
ByteEncodeSubscriptionReq receivedReq=new ByteEncodeSubscriptionReq();//server side POJO
System.out.println("ByteArrayServer: created SubscriptionReq Object");
InputStream PojoStreamHolder = servedClient.getInputStream();
System.out.println("ByteArrayServer: client InputStream received");
byte[] clientByteStream=new byte[44];//same size as Pojo byte requirement
_____/*MY CODE IS STUCK SOMEWHERE HERE*/__________
servedClient.getInputStream().read(clientByteStream);
System.out.println("ByteArrayServer: clientByteStream received: "+clientByteStream[0]+" "+clientByteStream[1]);
receivedReq=ByteEncodeSubscriptionReq.decode(clientByteStream);
//Send confirmation to Client__________________________________________________
DataOutputStream out = new DataOutputStream(servedClient.getOutputStream());
if(receivedReq.getRequestSymbol().trim().length()!=0){
out.writeUTF("ByteArrayServer received Subscription ID="+receivedReq.getSubscriptionID());
System.out.println("ByteArrayServer: new SubscriptionRequest ID="+receivedReq.getSubscriptionID()+" Subscriber_Name="+receivedReq.getSubscriberName());
}else{
out.writeUTF("ByteArrayServer: did not receive Subscription ID");
}
//Close Client socket_________________________________________________________
//server.close();
//serverSocket.close();
} catch (SocketTimeoutException s) {
System.out.println("PojoServer: Socket timed out after " + getTimeElapsedInSeconds(startTime) + " seconds from start");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
// int port = Integer.parseInt(args[0]);//to get port as an Argument
int port = 6060;
try {
Thread t = new ByteArrayServer(port);
startTime = System.currentTimeMillis();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是服务器控制台输出:
ByteArrayServer: Waiting for client on port 6060...
ByteArrayServer: connected to /127.0.0.1:64233
ByteArrayServer: created SubscriptionReq Object
ByteArrayServer: client InputStream received
问题是,虽然流被服务器正确接收,但它卡在 servedClient.getInputStream().read(clientByteStream) 附近;方法,不再继续。
我也试过了
int count=servedClient.getInputStream().read(clientByteStream);
和
DataInputStream in = new DataInputStream(servedClient.getInputStream());
long bStr=in.readLong();
和
ObjectInputStream PojoObjHolder = new ObjectInputStream(PojoStreamHolder);
byte[] clientByteStream2 = (byte[])PojoObjHolder.readObject();
..但它们也显示出同样的问题。
我应该如何在两个 class 之间传递字节数组而不需要额外的导入?
DataInputStream.readFully(byte[] b)
只有在输入流字节数达到 b.length 可用时才会完成。因此,如果您拥有所有字节或 not.And,您肯定需要进行调试,解决方案是使这些字节可用,以便函数完成。
DataInputStream.read(byte[] b) 相同 该方法被阻塞,直到输入数据可用。
请通过调试您的应用程序确保输入流有 44 个字节。
尝试在下面计算可用字节数,您可以轻松阅读这些内容。
// 计算输入流中的可用字节数
整数计数 = is.available();
// create buffer
byte[] bs = new byte[count];
// read data into buffer
dis.read(bs);
问题出在我的 ByteArrayClient Class 中。我不得不 link 带有客户端套接字的 OutputStream,而不是创建它的新实例。所以我更换了:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.write(SubscripReqByteArray);;
和
OutputStream os = client.getOutputStream(out);
os.write(SubscripReqByteArray);;
感谢 Ekant 的提示
我设计了一个 Java 客户端 class,它需要通过套接字将字节 [] 数组发送到 Java 服务器 class。这是我的代码:
ByteArrayClient.java
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ByteArrayClient {
public static void main(String[] args) {
//make POJO__________________________
ByteEncodeSubscriptionReq sr1=ByteEncodeSubscriptionReq.makeRequest(103, "Str1", "Str2");
//Connection details____________________
String serverName = "localhost";
int port = 6060;
try {
//Establish Connection with server_______________________________
System.out.println("ByteArrayClient: Connecting to " + serverName +":" + port+"...");
Socket client = new Socket(serverName, port);//make new socket
System.out.println("ByteArrayClient: connected to " + client.getRemoteSocketAddress());
//Encode POJO to ByteArray________________________________
byte[] SubscripReqByteArray=ByteEncodeSubscriptionReq.encode(sr1);
//encoded correctly to a 44 bit byte array
System.out.println("ByteArrayClient: SubscripTionRequest successfully encoded");
//Send POJO ByteArray to server__________________________
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.write(SubscripReqByteArray);;
System.out.println("ByteArrayClient: POJO sent to server");
//Receive Server response_________________________________
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("ByteArrayClient received: " + in.readUTF());
//close socket____________________________________
client.close();
} catch (IOException e) {
e.printStackTrace();
System.out.println("PojoClient: Connection Failed");
}
}
}
...和ByteArrayServer.java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
public class ByteArrayServer extends Thread{
private ServerSocket serverSocket;
public ByteArrayServer(int port) throws IOException {
serverSocket = new ServerSocket(port);//create server socket
serverSocket.setSoTimeout(15000);//socket closes after 15 seconds
this.start();
}
public void run() {
while (true) {//server runs infinitely______________
try {
System.out.println("ByteArrayServer: Waiting for client on port " + serverSocket.getLocalPort() + "...");
Socket servedClient = serverSocket.accept();//client socket
System.out.println("ByteArrayServer: connected to " + servedClient.getRemoteSocketAddress());
//Receive Client ByteArray___________________________________________
ByteEncodeSubscriptionReq receivedReq=new ByteEncodeSubscriptionReq();//server side POJO
System.out.println("ByteArrayServer: created SubscriptionReq Object");
InputStream PojoStreamHolder = servedClient.getInputStream();
System.out.println("ByteArrayServer: client InputStream received");
byte[] clientByteStream=new byte[44];//same size as Pojo byte requirement
_____/*MY CODE IS STUCK SOMEWHERE HERE*/__________
servedClient.getInputStream().read(clientByteStream);
System.out.println("ByteArrayServer: clientByteStream received: "+clientByteStream[0]+" "+clientByteStream[1]);
receivedReq=ByteEncodeSubscriptionReq.decode(clientByteStream);
//Send confirmation to Client__________________________________________________
DataOutputStream out = new DataOutputStream(servedClient.getOutputStream());
if(receivedReq.getRequestSymbol().trim().length()!=0){
out.writeUTF("ByteArrayServer received Subscription ID="+receivedReq.getSubscriptionID());
System.out.println("ByteArrayServer: new SubscriptionRequest ID="+receivedReq.getSubscriptionID()+" Subscriber_Name="+receivedReq.getSubscriberName());
}else{
out.writeUTF("ByteArrayServer: did not receive Subscription ID");
}
//Close Client socket_________________________________________________________
//server.close();
//serverSocket.close();
} catch (SocketTimeoutException s) {
System.out.println("PojoServer: Socket timed out after " + getTimeElapsedInSeconds(startTime) + " seconds from start");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String[] args) {
// int port = Integer.parseInt(args[0]);//to get port as an Argument
int port = 6060;
try {
Thread t = new ByteArrayServer(port);
startTime = System.currentTimeMillis();
} catch (IOException e) {
e.printStackTrace();
}
}
}
这是服务器控制台输出:
ByteArrayServer: Waiting for client on port 6060...
ByteArrayServer: connected to /127.0.0.1:64233
ByteArrayServer: created SubscriptionReq Object
ByteArrayServer: client InputStream received
问题是,虽然流被服务器正确接收,但它卡在 servedClient.getInputStream().read(clientByteStream) 附近;方法,不再继续。
我也试过了
int count=servedClient.getInputStream().read(clientByteStream);
和
DataInputStream in = new DataInputStream(servedClient.getInputStream());
long bStr=in.readLong();
和
ObjectInputStream PojoObjHolder = new ObjectInputStream(PojoStreamHolder);
byte[] clientByteStream2 = (byte[])PojoObjHolder.readObject();
..但它们也显示出同样的问题。
我应该如何在两个 class 之间传递字节数组而不需要额外的导入?
DataInputStream.readFully(byte[] b)
只有在输入流字节数达到 b.length 可用时才会完成。因此,如果您拥有所有字节或 not.And,您肯定需要进行调试,解决方案是使这些字节可用,以便函数完成。
DataInputStream.read(byte[] b) 相同 该方法被阻塞,直到输入数据可用。
请通过调试您的应用程序确保输入流有 44 个字节。
尝试在下面计算可用字节数,您可以轻松阅读这些内容。
// 计算输入流中的可用字节数 整数计数 = is.available();
// create buffer
byte[] bs = new byte[count];
// read data into buffer
dis.read(bs);
问题出在我的 ByteArrayClient Class 中。我不得不 link 带有客户端套接字的 OutputStream,而不是创建它的新实例。所以我更换了:
ByteArrayOutputStream out = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(out);
os.write(SubscripReqByteArray);;
和
OutputStream os = client.getOutputStream(out);
os.write(SubscripReqByteArray);;
感谢 Ekant 的提示