繁体   English   中英

使用ServerSocket和HTML客户端上传文件。 卡在InputStream.read()

[英]File upload using ServerSocket & HTML Client. Stuck at InputStream.read()

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

服务器:

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客户端如下:

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页面。

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); 服务器代码。

控制台日志

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

可能是什么原因?

还有一个问题...

最终,我试图理解的是上传文件时“ multipart / form-data”的目的(一旦我使上述代码正常工作,这就是我计划进行的实验)。 如果有人可以给我提示,那将非常有帮助。

这很好。

不,不是。 它在文件末尾以及可能在其他地方写入垃圾。 您的复制循环应为:

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

在服务器和客户端中。

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

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

从oracle文档:

套接字是网络上运行的两个程序之间双向通讯链接的一个端点。 套接字类用于表示客户端程序和服务器程序之间的连接。 java.net包提供了两个类Socket和ServerSocket,它们分别实现连接的客户端和连接的服务器。

简单的套接字客户端是:

 Socket echoSocket = new Socket(hostName, portNumber);
    PrintWriter out =
        new PrintWriter(echoSocket.getOutputStream(), true);
    BufferedReader in =
        new BufferedReader(
            new InputStreamReader(echoSocket.getInputStream()));

此处使用的Socket构造函数需要计算机的名称和您要连接的端口号。

简单的套接字服务器是:

 ServerSocket serverSocket = new ServerSocket(portNumber);
    Socket clientSocket = serverSocket.accept();
    PrintWriter out =
        new PrintWriter(clientSocket.getOutputStream(), true);
    BufferedReader in = new BufferedReader(
        new InputStreamReader(clientSocket.getInputStream()));

ServerSocket是java.net类,它提供服务器端的独立于系统的实现。 要接受来自客户端ServerSocket连接,请执行以下操作:

clientSocket = serverSocket.accept();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM