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

落爺英雄遲暮 提交于 2019-12-08 10:28:30

问题


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).

Server:

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 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();
    }

}

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>

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.

Console log..

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

What can be the possible reason?

One more question...

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.


回答1:


This works fine.

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);
}

in both server and client.

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

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.




回答2:


From oracle docs:

A socket is one end-point of a two-way communication link between two programs running on the network. Socket classes are used to represent the connection between a client program and a server program. The java.net package provides two classes--Socket and ServerSocket--that implement the client side of the connection and the server side of the connection, respectively.

Simple socket client is :

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

The Socket constructor used here requires the name of the computer and the port number to which you want to connect.

Simple socket server is:

 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 is a java.net class that provides a system-independent implementation of the server side. To accept connection from client ServerSocket does:

clientSocket = serverSocket.accept();


来源:https://stackoverflow.com/questions/45024852/file-upload-using-serversocket-html-client-stuck-at-inputstream-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!