使用 ServerSocket & 上传文件HTML 客户端.卡在 InputStream.read() [英] File upload using ServerSocket & HTML Client. Stuck at InputStream.read()

查看:61
本文介绍了使用 ServerSocket & 上传文件HTML 客户端.卡在 InputStream.read()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了理解套接字编程的概念,我创建了一个服务器和一个客户端.客户端将发送一个文件,服务器应将其保存在某个位置.(即文件上传).

To understand the concept of socket programming, I created a server and a client. The client will send a file and server should save it some location. (ie. a file upload).

服务器:

package com.test.socket.server;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class WebServer {

    public static void main(String[] args) throws IOException {


        ServerSocket serverSocket = new  ServerSocket(8081);

        Socket socket = serverSocket.accept();

        System.out.println("Received request");


        InputStream inputStream = socket.getInputStream();

        OutputStream out = new FileOutputStream("yoyo.png");

        System.out.println("Reading....");

        byte[] bytes = new byte[16 * 1024];

        int count = 0;
        while((count = inputStream.read(bytes)) > 0){
        System.out.print(". ");
        out.write(bytes,0,count);
        System.out.println("Some bytes are written");
        }

        System.out.println("written....");

        socket.getOutputStream().write("Written.....".getBytes());

        out.close();
        inputStream.close();
        socket.close();
        serverSocket.close();


    }

}

Java 客户端如下:

Java client follows:

package com.test.socket.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class WebClient {

    public static void main(String[] args) throws UnknownHostException, IOException {

        Socket socket = null;
        String host = "127.0.0.1";

        socket = new Socket(host, 8081);

        ///home/renju/Desktop/frame.png

        File file = new File("/home/renju/Desktop/frame.png");

        InputStream inputStream = new FileInputStream(file);

        OutputStream os = socket.getOutputStream();

        byte[] bytes = new byte[16 * 1024];

        int count = 0;
        while((count = inputStream.read(bytes)) > 0){
            os.write(bytes);
        }

        System.out.println("Sending....");

        os.close();
        inputStream.close();
        socket.close();
    }

}

这工作正常并将上传的文件写入我的项目根文件夹.现在我将客户端更改为 HTML 页面.

This works fine and writes the uploaded file to my projects root folder. Now I changed the client to an HTML page.

HTML:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

    <form action="http://127.0.0.1:8081/" method="POST">

        <input type="file" name="file" />
        <button type="submit" name="submit">Upload</button>

    </form>

</body>
</html>

这与 Java 客户端的工作方式不同.出于某种原因,执行没有超出服务器代码的out.write(bytes);.

This is not working in the same fashion as the Java client. For some reason, the execution does not go beyond the out.write(bytes); of server code.

控制台日志..

Received request
Reading....
. Some bytes are written

可能的原因是什么?

还有一个问题...

最终我想了解的是上传文件时multipart/form-data"的目的(一旦我让上面的代码工作,这就是我计划进行的实验).如果有人可以给我一个提示,那将非常有帮助.

Ultimately what I am trying to understand is the purpose of 'multipart/form-data' while uploading a file(once I got the above code working, that is what I am planning to experiment). If someone could give me a hint on that, it will be really helpful.

推荐答案

这很好用.

不,不是.它在文件末尾写入垃圾,也可能在其他地方.您的复制循环应该是:

No it doesn't. It writes junk at the end of the file, and possibly in other places as well. Your copy loop should be:

while((count = inputStream.read(bytes)) > 0){
    System.out.print(". ");
    out.write(bytes, 0, count);
}

在服务器和客户端.

由于某种原因,执行没有超出out.write(bytes);服务器代码.

For some reason, the execution does not go beyond the out.write(bytes); of server code.

实际上它阻塞在read(),而不是write().那是因为您现在收到一个 HTTP 请求,特别是因为 HTTP keepalive.请参阅 RFC 2616 和后续版本.您编写的服务器代码会将所有 HTTP 标头写入目标文件,然后阻塞直到客户端浏览器释放连接,这可能需要任意长的时间.您需要读取解析标头,特别是Content-lengthContent-encoding标头,并处理相应的请求正文,这意味着仅尝试读取 Content-length 中给出的字节数,而不是读取到流的末尾,并且如果 Content-encoding是分块的,你需要写一些分块的代码.

Actually it is blocking in read(), not write(). That is because you are now getting an HTTP request, and specifically it is because of HTTP keepalive. See RFC 2616 and successors. The server code you've written will write all the HTTP headers to the target file and then block until the client browser releases the connection, which can take an arbitrary amount of time. You need to read and parse the headers, specifically the Content-length and Content-encoding headers, and process the body of the request accordingly, which means only trying to read the number of bytes given in Content-length, not read to end of stream, and if the Content-encoding is chunked, you need to write some unchunking code.

这篇关于使用 ServerSocket &amp; 上传文件HTML 客户端.卡在 InputStream.read()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆