为什么socket只发送1KB(425B)的数据?
Why socket send only 1KB (425B) of data?
我正在学习套接字,现在想编写文件传输程序。我有服务器部分和客户端部分。服务器部分包含 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, 0, count);
secondOutput.write(bytes, 0, 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, 0, count);
}
outputStream.close();
inputStream.close();
inSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
bug在哪里?为什么在本地一切正常时只发送空字节?
你可以这样做:
@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
),虽然read(byte[])
只有 return 0
如果传入的字节数组的长度为零,所以这不是真正的问题。
我正在学习套接字,现在想编写文件传输程序。我有服务器部分和客户端部分。服务器部分包含 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, 0, count);
secondOutput.write(bytes, 0, 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, 0, count);
}
outputStream.close();
inputStream.close();
inSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
bug在哪里?为什么在本地一切正常时只发送空字节?
你可以这样做:
@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
),虽然read(byte[])
只有 return 0
如果传入的字节数组的长度为零,所以这不是真正的问题。