我希望通过TCP套接字连接从客户端向服务器发送JPG图像。我将文件转换为客户端中的字节数组,然后在发送数组长度后将其发送到服务器。服务器一次一个字节地从socketinputstream读取数据到新的bytearray,然后将其写入jpg文件。但是数据已损坏,无法查看此图像。下面是客户端和服务器的核心Java代码。
客户端:
Socket s = new Socket("localhost", 666);
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
String imgPath = "C:/Users/huehuehue/Documents/Uni/D0036D/prick1.JPG";
File file = new File(imgPath);
byte[] b = new byte[(int) file.length()];
FileInputStream fis = new FileInputStream(file);
fis.read(b);
fis.close();
dos.writeInt((int) file.length());
dos.flush();
dos.write(b, 0, b.length);
dos.flush();
服务器:
ServerSocket serverSocket = new ServerSocket(666);
Socket connect = serverSocket.accept();
DataInputStream dis = new DataInputStream(connect.getInputStream());
File file = new File("C:/Users/huehuehue/Documents/Uni/D0036D/PLAYERprick.JPG");
FileOutputStream fos = new FileOutputStream(file);
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
int i = 0;
for(i = 0; i < arrlen; i++) {
b[i] = dis.readByte();
i++;
}
fos.write(b, 0 , b.length);
我无法理解为什么这不起作用,我们非常感谢任何帮助或建议。
答案 0 :(得分:1)
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
int i = 0;
for(i = 0; i < arrlen; i++) {
b[i] = dis.readByte();
i++;
}
您将i
递增两次,以便忽略输入的一半,并将您不会忽略的内容写入错误的广告位。幸运的是,有一种更简单的方法,也更有效:
int arrlen = dis.readInt();
byte[] b = new byte[arrlen];
dis.readFully(b);
NB fis.read(b);
无效。你不能假设它填充了缓冲区。你也应该在这里使用DataInputStream.readFully()
。
答案 1 :(得分:0)
您需要匹配套接字的两端,而您的客户端并未完全填充byte[]
;相反,您的客户端可以在读取时发送每个字节。而且,由于Java提供BufferedInputStream
,您不必直接手动使用和调整byte[]
缓冲区。相反,你可以做类似的事情,
Socket s = new Socket("localhost", 666);
String imgPath = "C:/Users/huehuehue/Documents/Uni/D0036D/prick1.JPG";
File file = new File(imgPath);
try (InputStream is = new BufferedInputStream(new FileInputStream(file));
DataOutputStream dos = new DataOutputStream(s.getOutputStream());) {
dos.writeLong(file.length()); // <-- remember to read a long on server.
int val;
while ((val = is.read()) != -1) {
dos.write(val);
}
dos.flush();
}
此外,您的服务器可以使用类似的BufferedOutputStream
来获得像
ServerSocket serverSocket = new ServerSocket(666);
File file = new File("C:/Users/huehuehue/Documents/Uni/D0036D/PLAYERprick.JPG");
try (Socket s = serverSocket.accept();
DataInputStream dis = new DataInputStream(
s.getInputStream());
OutputStream fos = new BufferedOutputStream(
new FileOutputStream(file));) {
long arrlen = dis.readLong();
for (long i = 0; i < arrlen; i++) {
fos.write(dis.read());
}
fos.flush();
}
无需手动管理。请注意,上面使用BufferedInputStream
和BufferedOutputStream
来管理缓冲作为优化。您可以删除它们并直接从File
流进行读写。