问题
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