如何从 java 上的套接字读取多种类型的数据
How to read multiple types of data from socket on java
我写了一些文件传输应用程序。在客户端和服务器之间我发送 3 种类型的数据:
1) 有些 "command words" 喜欢 READY_FOR_UPLOAD.
2) 一些可序列化的数据
3) 字节数组中的大文件。
我在服务器套接字上获得客户端连接并为每个客户端创建新线程。
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {}
我使用 try with resources 创建这些流,没有问题。
我使用:
1) "in" 用于读取来自客户端的消息:
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
2)"out" 用于发送消息。
3)"inputStream" 接收文件:
try (FileOutputStream fileOutputStream = new
FileOutputStream("D:\testDownload.zip");
BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(fileOutputStream)
) {
byte[] buffer = new byte[1024 * 100];
int read;
while ((read = inputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, read);
}
}
4) "objectInputStream" 对于可序列化数据:
Object object;
if ((object = objectInputStream.readObject()) != null) {
if (object instanceof File) {
File file = (File) object;
System.out.println(file.getAbsolutePath());
System.out.println(file.length());
}
}
虽然我单独使用它们 - 没有问题。但我需要首先阅读 "command word",即在我的方法 运行 开始时。
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
String line;
if ((line = in.readLine()) != null) {
System.out.println(line);
there i should try to read other types of data
}
}
如果这不是 "command word" 我可以尝试读取可序列化数据或文件数据。但这是一个问题!我可能会尝试读取一行,但它可以是文件数据的可序列化数据的一部分,并且因为输入流读取 "one-by-one" 字节方法,我不能尝试像可序列化或文件数据一样读取它,因为输入不再完整,我读取 "readLine()" 中的一些数据。在我尝试阅读之前,我应该知道我收到的是什么类型的数据。怎么做到的?
您需要创建一个协议 - 规定客户端和服务器如何在它们之间交换信息。
当您写入数据时,您指定要发送的数据类型及其大小。并且不要在 Socket 上使用 ObjectInputStream 和 ObjectOutputStream - 将数据转换为字节数组,以便您在写入时知道大小是多少,然后将它们转换回来。以字节形式发送数据。
我写了一些文件传输应用程序。在客户端和服务器之间我发送 3 种类型的数据:
1) 有些 "command words" 喜欢 READY_FOR_UPLOAD.
2) 一些可序列化的数据
3) 字节数组中的大文件。
我在服务器套接字上获得客户端连接并为每个客户端创建新线程。
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {}
我使用 try with resources 创建这些流,没有问题。
我使用:
1) "in" 用于读取来自客户端的消息:
String line;
while ((line = in.readLine()) != null) {
System.out.println(line);
}
2)"out" 用于发送消息。
3)"inputStream" 接收文件:
try (FileOutputStream fileOutputStream = new
FileOutputStream("D:\testDownload.zip");
BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(fileOutputStream)
) {
byte[] buffer = new byte[1024 * 100];
int read;
while ((read = inputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, read);
}
}
4) "objectInputStream" 对于可序列化数据:
Object object;
if ((object = objectInputStream.readObject()) != null) {
if (object instanceof File) {
File file = (File) object;
System.out.println(file.getAbsolutePath());
System.out.println(file.length());
}
}
虽然我单独使用它们 - 没有问题。但我需要首先阅读 "command word",即在我的方法 运行 开始时。
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(),true);
InputStream inputStream = clientSocket.getInputStream();
ObjectInputStream objectInputStream = new ObjectInputStream(inputStream)) {
String line;
if ((line = in.readLine()) != null) {
System.out.println(line);
there i should try to read other types of data
}
}
如果这不是 "command word" 我可以尝试读取可序列化数据或文件数据。但这是一个问题!我可能会尝试读取一行,但它可以是文件数据的可序列化数据的一部分,并且因为输入流读取 "one-by-one" 字节方法,我不能尝试像可序列化或文件数据一样读取它,因为输入不再完整,我读取 "readLine()" 中的一些数据。在我尝试阅读之前,我应该知道我收到的是什么类型的数据。怎么做到的?
您需要创建一个协议 - 规定客户端和服务器如何在它们之间交换信息。 当您写入数据时,您指定要发送的数据类型及其大小。并且不要在 Socket 上使用 ObjectInputStream 和 ObjectOutputStream - 将数据转换为字节数组,以便您在写入时知道大小是多少,然后将它们转换回来。以字节形式发送数据。