上传文件停止并在套接字异常上读取意外的 EOF

Posted

技术标签:

【中文标题】上传文件停止并在套接字异常上读取意外的 EOF【英文标题】:Upload file stop with Unexpected EOF read on the socket Exception 【发布时间】:2016-04-10 14:55:28 【问题描述】:

有时当我尝试在远程 vps 上上传文件时出现此异常(上传过程停止在 60%)

06-Jan-2016 11:59:36.801 SEVERE [http-nio-54000-exec-9] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Request processing failed;
nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request;
nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket]
with root cause
 java.io.EOFException: Unexpected EOF read on the socket

Google Chrome 中,连接丢失,就像服务器关闭一样,我得到ERR_CONNECTION_ABORTED

我在spring mvc中上传这样的文件

public void save_file(MultipartFile upfile , String path)

        try 

            File fichier = new File( path ) ;
            byte[] bytes = upfile.getBytes();
            BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
            stream.write(bytes);
            stream.close();
            System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );

         catch (Exception e) 
            System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
        


我的控制器:

@RequestMapping(value = "/administration/upload", method = RequestMethod.POST)
public String Upload_AO_journal(
        @ModelAttribute  UploadForm uploadForm,
                Model map , HttpServletRequest request, HttpSession session ) throws ParseException, UnsupportedEncodingException 

我的豆子

public class UploadForm 

    ...
    public MultipartFile scan;

那么如何解决这个问题呢?

【问题讨论】:

所有文件大小都失败,还是小文件成功?您可以分享将请求映射到此方法的特定于 spring 的代码吗? @tdimmig 有时它会失败,有时对于相同的大小它是好的!我更新了我的问题。 看看这个答案能不能帮到你:***.com/a/18543887/4056187 【参考方案1】:

你试过直播吗?

jsp代码:

<form method="POST" onsubmit="" ACTION="url?$_csrf.parameterName=$_csrf.token" ENCTYPE="multipart/form-data">

控制器:

 @RequestMapping(
        value = "url", method = RequestMethod.POST
)
public void uploadFile(
        @RequestParam("file") MultipartFile file
) throws IOException 

 InputStream input = upfile.getInputStream();
 Path path = Paths.get(path);//check path
 OutputStream output = Files.newOutputStream(path);
 IOUtils.copy(in, out); //org.apache.commons.io.IOUtils or you can create IOUtils.copy


spring 4.0 和 spring security 对我有用。

其次,您应该检查http连接是否超时。 Chrome 不支持该配置。所以你可以使用 Firefox 并关注这里http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html

【讨论】:

文件的 apache api 比文件的默认 java api 更安全? 我使用它,只是因为它干净且经过测试。我不认为它更安全。 @Youssef 我面临着类似的问题,但在我的情况下,我在 finally 块中关闭流。这里不需要关闭输入输出流吗?【参考方案2】:

不确定 upfile 上的 getBytes() 方法。更合适的方法是使用 InputStream 来管理任何大小的文件,并在必要时进行缓冲。比如:

public void save_file(MultipartFile upfile , String path)

    try 
        File fichier = new File( path ) ;
        BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
        InputStream is = upfile.getInputStream();
        byte [] bytes = new byte[1024];
        int sizeRead;
        while ((sizeRead = is.read(bytes,0, 1024)) > 0) 
            stream.write(bytes, 0, sizeRead);
        
        stream.flush();
        stream.close();
        System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );

     catch (Exception e) 
        System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
    


【讨论】:

为什么是new byte[1024]?大小将除以 1024 ? 你可以把它做成你需要的任何大小,1024是1K,通常是下载性能最高的大小。你试过了吗? 还没回家我试试【参考方案3】:

出现此问题是因为您关闭流直到流写入整个数据。

错误的方式:

stream.write(bytes);
stream.close();

正确的方式:

try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier))) 

    stream.write(data);

您应该在写入整个数据后关闭您的流。

【讨论】:

当然,stream.close() 应该放到 finally 块中。【参考方案4】:

我遇到了类似的问题,问题是当您上传文件时,您正在使用 Multipart Form POST 请求。您可以阅读有关MIME 的信息。

MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier

This is a message with multiple parts in MIME format.
--frontier
Content-Type: text/plain

This is the body of the message.
--frontier
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64

PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--frontier--

我遇到的基本问题是请求中的多部分具有元信息部分、文本部分和我相信 base64 编码的实际文件。每个部分都按边界分割。如果您没有正确设置此边界(在上面的示例中,它被称为“边界”),服务器开始读取文件,但在到达 EOF 之前不知道它在哪里结束,并返回有关意外 EOF 的错误,因为它没有找到所需的边界。

您的代码的问题是您正在将文件写入 ByteOutputStream,这适用于将文件从服务器返回给用户而不是其他方式。服务器期望这个 Multipart 请求带有一些标准的预定义格式。使用Apache Commons HttpClient 库为您完成所有这些请求格式和边界设置。如果你使用 Maven,那么this link。

File f = new File("/path/fileToUpload.txt");
PostMethod filePost = new PostMethod("http://host/some_path");
Part[] parts = 
  new StringPart("param_name", "value"),
  new FilePart(f.getName(), f)
;
filePost.setRequestEntity(
  new MultipartRequestEntity(parts, filePost.getParams())
  );
HttpClient client = new HttpClient();
int status = client.executeMethod(filePost);

免责声明:代码不是我的,它是来自Apache website for multipart request的示例

【讨论】:

从他的问题我了解到他是从 Spring 客户端上传的,因为他说“我在 spring mvc 中上传这样的文件”这就是为什么我认为他是从客户端上传的原因 我猜他的意思是“进入”。他在客户端使用谷歌浏览器上传,服务器端有 Spring MVC。 @MichaelDD 是的,我使用浏览器 哦,抱歉,我没有正确理解这个问题。从客户端上传时我遇到了同样的问题,所以我认为这也是你的情况 没问题兄弟..我可以在未来面对你的问题【参考方案5】:

当我没有正确设置要放置文件的路径时,我遇到了同样的错误。

解决方法是这样改变它:

factoryMaster.setCertificateFile("E:\\Project Workspace\\Live Projects\\fileStore\\Factory Master\\"+factoryMasterBean.getFile().getOriginalFilename());

并在控制器中使用 throws 异常:

public @ResponseBody ResponseEntity<FactoryMaster> saveFactoryMaster(@ModelAttribute("factoryMasterBean") FactoryMasterBean factoryMasterBean,FactoryMaster factoryMaster) throws IllegalStateException, IOException ...............  

并确保不要发送任何已存在的同名文件。

【讨论】:

以上是关于上传文件停止并在套接字异常上读取意外的 EOF的主要内容,如果未能解决你的问题,请参考以下文章

SecureCRT使用sftp上传较大文件意外暂停

Vichuploader 破坏实体 - 意外的 EOF

org.eclipse.jetty.io.EofException:上传大文件时抛出早期 EOF

拿来。 Stripe 集成在本地主机上工作,并在上传到 Firebase 后停止工作

发送图像时出现 Python 套接字错误。无法解码字节/意外 EOF

上传 CSV 文件并在 Bokeh Web 应用程序中读取