使用ServerSocket和HTML Client上传文件。 陷入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:

     Insert title here   

在此处输入图像描述

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

控制台日志..

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

可能的原因是什么?

还有一个问题…

最终我想要了解的是在上传文件时“多部分/表单数据”的目的(一旦我上面的代码工作,这就是我计划实验的内容)。 如果有人可以给我一个提示,那将非常有帮助。

这很好用。

不,不。 它在文件末尾写入垃圾,也可能在其他地方写入垃圾。 你的副本循环应该是:

 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被分块,你需要编写一些unchunking代码。

来自oracle docs:

套接字是网络上运行的两个程序之间的双向通信链路的一个端点。 套接字类用于表示客户端程序和服务器程序之间的连接。 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();