问题描述
我正在学习套接字,现在我想编写文件传输程序。我有服务器部分和客户端部分。服务器部分包含 2 个端口:5000(命令)和 5001(文件)。现在我想通过套接字发送一个文件,当我做一些事情时出错了,因为只有 425B 的数据正在发送。
这是客户端发送方法:
private void sendFile(Socket socket) {
File file2 = new File("C:\\Users\\barte\\Desktop\\dos.png");
byte[] bytes = new byte[16 * 1024];
System.out.println(file2.exists());
try (InputStream inputStream = new FileInputStream(file2);
OutputStream outputStream = socket.getoutputStream();
OutputStream secondOutput = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\dos.png")) {
int count;
while ((count = inputStream.read(bytes)) > 0) {
outputStream.write(bytes,count);
secondOutput.write(bytes,count);
}
socket.close();
} catch (IOException e) {
e.printstacktrace();
}
}
如您所见(下图)我也在本地写入此文件,一切正常,所有 73KB 数据都已写入。
现在,在服务器端我试图接收这个文件:
case SEND: {
new Thread(() -> {
printWriter.println("Server is receiving files right Now...");
try (ServerSocket serverSocket = new ServerSocket(5001)) {
while (true) {
new FilesTransfer(serverSocket.accept()).start();
}
} catch (IOException e) {
e.printstacktrace();
}
}).start();
break;
}
在 FilesTransfer 中运行方法:
@Override
public void run() {
System.out.println("Hello there");
try {
InputStream inputStream = inSocket.getInputStream();
OutputStream outputStream = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\file");
byte[] bytes = new byte[16 * 1024];
int count;
while ((count = inputStream.read()) > 0) {
outputStream.write(bytes,count);
}
outputStream.close();
inputStream.close();
inSocket.close();
} catch (IOException e) {
e.printstacktrace();
}
}
错误在哪里?为什么本地一切正常时只发送空字节?
解决方法
你可以这样做:
@Override
public void run() {
System.out.println("Hello there");
try {
InputStream inputStream = inSocket.getInputStream();
OutputStream outputStream = new FileOutputStream("C:\\Users\\barte\\Desktop\\received\\file");
byte[] bytes = new byte[16 * 1024];
int byteRead= 1;
while (byteRead > -1) {
byteRead= inputStream.read();
outputStream.write(byteRead);
}
outputStream.close();
inputStream.close();
inSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
实际上 END OF FILE 或 EOF 的意思是 -1 而你做了 > 0 所以取了 0 并且它停止了保存文件的连接。
我还建议编写一个逻辑来将文件名作为命令传输到服务器,以便使用正确的名称和扩展名保存文件!
,问题是:
while ((count = inputStream.read()) > 0) {
您的代码使用 InputStream.read()
,它读取单个字节(或在流结束时读取 -1
)。现在,您正在读取单个字节,将其解释为长度,然后将 bytes
中的 0x00 字节数写入文件。当您从流中读取 0x00 字节时,这会停止。
您需要将其更改为使用 InputStream.read(byte[])
:
while ((count = inputStream.read(bytes)) != -1) {
也就是说,您需要传入bytes
,并检查结果是否不等于-1
,而不是大于零(0
),尽管{{1 }} 只会在传入的字节数组长度为零时返回 read(byte[])
,因此这不是真正的问题。