Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-文件通过套接字发送时会损坏,但发送到本地主机时除外_Java_Sockets - Fatal编程技术网

Java-文件通过套接字发送时会损坏,但发送到本地主机时除外

Java-文件通过套接字发送时会损坏,但发送到本地主机时除外,java,sockets,Java,Sockets,我正在尝试使用套接字在Java中构建文件服务器和文件客户端程序,在尝试将文件从服务器发送到客户端时遇到了一些问题。下面是我分别用来发送和接收文件的代码: private void sendFile(String filePath) { try (BufferedInputStream fileInputStream = new BufferedInputStream(new FileInputStream(filePath))) { BufferedOutputStrea

我正在尝试使用套接字在Java中构建文件服务器和文件客户端程序,在尝试将文件从服务器发送到客户端时遇到了一些问题。下面是我分别用来发送和接收文件的代码:

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”时,这个问题不会出现,那么就没有问题,下载的文件也没有损坏。查看我的代码中的任何问题?在SeNFLIVER()中,您需要考虑从Read()中返回的值,该值可能小于4096。然后,应在写入调用中使用此值,以仅写出已填充的数组部分

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的精确倍数


您下载了一个文件并事先知道文件大小?这很不寻常-如何调用downloadFile?谢谢,但您知道为什么在本地主机上这些问题不会导致文件损坏吗?
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;
}