Java-文件通过套接字发送时会损坏,但发送到本地主机时除外
我正在尝试使用套接字在Java中构建文件服务器和文件客户端程序,在尝试将文件从服务器发送到客户端时遇到了一些问题。下面是我分别用来发送和接收文件的代码:Java-文件通过套接字发送时会损坏,但发送到本地主机时除外,java,sockets,Java,Sockets,我正在尝试使用套接字在Java中构建文件服务器和文件客户端程序,在尝试将文件从服务器发送到客户端时遇到了一些问题。下面是我分别用来发送和接收文件的代码: private void sendFile(String filePath) { try (BufferedInputStream fileInputStream = new BufferedInputStream(new FileInputStream(filePath))) { BufferedOutputStrea
private void sendFile(String filePath) {
try (BufferedInputStream fileInputStream = new BufferedInputStream(new FileInputStream(filePath))) {
BufferedOutputStream outputStream = new BufferedOutputStream(socket.getOutputStream());
byte[] buffer = new byte[4096];
while (fileInputStream.read(buffer) != -1) {
outputStream.write(buffer);
outputStream.flush();
}
}
catch (IOException e) {e.printStackTrace();}
}
private void下载文件(字符串文件名,长文件大小){
try(BufferedOutputStream fileOutputStream=new BufferedOutputStream(new fileOutputStream(downloadDir+“/”+文件名));
BufferedInputStream inputStream=新的BufferedInputStream(socket.getInputStream());
OutputStreamWriter writer=新的OutputStreamWriter(新的BufferedOutputStream(socket.getOutputStream()),“UTF-8”);){
write(“GET”+fileName+System.lineSeparator());
writer.flush();
长期总接收=0;
int bufferSize=4096;
字节[]缓冲区=新字节[bufferSize];
while(总接收<文件大小){
inputStream.read(缓冲区);
int numobytestowrite=fileSize-totalReceived>bufferSize?buffer.length:(int)(fileSize%bufferSize);
write(缓冲区,0,numOfBytesToWrite);
fileOutputStream.flush();
totalReceived+=numobytestowrite;
}
}
捕获(IOE){}
}
下载的文件确实会被创建,看起来大小合适,但总是会被破坏,无法被任何程序打开。但是,当我在同一台机器上运行客户端并将其连接到“localhost”或“127.0.0.1”时,这个问题不会出现,那么就没有问题,下载的文件也没有损坏。查看我的代码中的任何问题?int bytesRead = 0;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
outputStream.flush();
}
downloadFile()中也出现类似问题,return from read()是实际读取的字节数,有些值小于或等于4096
long totalReceived = 0;
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
while (totalReceived < fileSize) {
int bytesRead = inputStream.read(buffer);
fileOutputStream.write(buffer, 0, bytesRead);
fileOutputStream.flush();
totalReceived += bytesRead;
}
long totalReceived=0;
int bufferSize=4096;
字节[]缓冲区=新字节[bufferSize];
while(总接收<文件大小){
int bytesRead=inputStream.read(缓冲区);
写入(缓冲区,0,字节读取);
fileOutputStream.flush();
totalReceived+=字节读取;
}
为什么您的代码在本地主机上工作,而不是在网络上工作
- 网络的典型物理层是以太网,其MTU为1500字节。因此,您可能会看到连续的read()调用只占用1500个字节或更少的缓冲区
- 但是,本地主机在堆栈中进行了优化,以绕过不受此限制的物理层。在这种情况下,除了上一次调用外,后续调用很可能会填满整个4096缓冲区,除非您的文件大小是4096的精确倍数
long totalReceived = 0;
int bufferSize = 4096;
byte[] buffer = new byte[bufferSize];
while (totalReceived < fileSize) {
int bytesRead = inputStream.read(buffer);
fileOutputStream.write(buffer, 0, bytesRead);
fileOutputStream.flush();
totalReceived += bytesRead;
}