`
gaojingsong
  • 浏览: 1204940 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

【基于Socket模拟Http协议上传文件】

阅读更多

永久链接: http://gaojingsong.iteye.com/blog/2414484

预览文章: 【Http文件上传协议解析】

 

核心代码:

import java.io.BufferedReader;

import java.io.File;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.net.InetAddress;

import java.net.Socket;

import java.net.URL;

import java.net.UnknownHostException;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.Random;

 

 

public class SocketUploadUtil {

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

// 判断端口号

int port = 9090;

// 构建socket,用于与服务器的联接

Socket socket = new Socket("127.0.0.1", port);

String path ="http://localhost:9090/mgr/upload";

String file = "c:/examples.cfg";

 

HashMap<String, String> params = new HashMap<String, String>();

params.put("email", "demo@123.com");

 

FileProperty f = new FileProperty("examples.cfg", new File(file), "file1", "text/plain");

List<FileProperty> files = new ArrayList<FileProperty>();

files.add(f);

uploadFile(socket,port, path, params,files);

}

/**

* descript: 用于文件上传的帮助类

* 直接通过http协议提交数据到服务器。 实现类似于下面web页面提交数据的功能 

<form method="post" 

 action="upload" 

 enctype="multipart/form-data">

 

<label>email:</label>

<input type="text" name="email" value="kickscar@gmail.com">

<br><br>

 

<label>File1:</label>

<input type="file" name="file1">

<br><br>

 

<label>File2:</label>

<input type="file" name="file2">

<br><br>

 

<br>

<input type="submit" value="upload">

</form>

* @throws IOException

* @throws UnknownHostException

*/

public static boolean uploadFile(Socket socket,int port,

String path, Map<String, String> params,

List<FileProperty> files) throws UnknownHostException, IOException {

Random r=new Random();

// 属性数据的分隔线

final String BOUNDARY = "---------------------------"+ r.nextInt(9999999);

final String ENDLINE = "--" + BOUNDARY + "--\r\n";

long fileInEntityDataLength = 0; // 存http协议实体部分文件数据的总长度

// 下面开始计算http协议实体部分的总长度

// 1.先计算文件部分包括文件属性和文件内容的长度

for (FileProperty uploadFile : files) {

StringBuilder sb = new StringBuilder();

sb.append("--");

sb.append(BOUNDARY);

sb.append("\r\n");

sb.append("Content-Disposition: form-data; name=\""

+ uploadFile.getParameterName() + "\";filename=\""

+ uploadFile.getFileName() + "\"\r\n");

sb.append("Content-Type: " + uploadFile.getContenttype()

+ "\r\n\r\n");

sb.append("\r\n");

// 以上形成了文件的属性值部分的参数长度

fileInEntityDataLength += sb.toString().length();

// 再加上文件内容的总长度

if (uploadFile.getInputStream() != null) { // 如果用的是文件流的话,就计算流文件长度

fileInEntityDataLength += uploadFile.getFile().length();

} else { // 否则计算二进制文件长度

fileInEntityDataLength += uploadFile.getData().length;

}

}

// 2.再计算文本属性部分的长度

StringBuilder sb2 = new StringBuilder();

for (Map.Entry<String, String> entry : params.entrySet()) {

sb2.append("--");

sb2.append(BOUNDARY);

sb2.append("\r\n");

sb2.append("Content-Disposition: form-data; name=\""

+ entry.getKey() + "\"\r\n\r\n");

sb2.append(entry.getValue());

sb2.append("\r\n");

}

// 计算传输给服务器的实体数据的总长度

// 实体数据总长度=文本数据总长+文件内容总长+结束语长度

long datalength = sb2.toString().getBytes().length + fileInEntityDataLength+ ENDLINE.getBytes().length;

 

// 构建URL对象,用于联接网络

URL url = new URL(path);

// 输出流

OutputStream outputStream = socket.getOutputStream();

 

// 下面完成http请求头的拼接和发送

StringBuffer protocal = new StringBuffer( "POST " + url.getPath() + " HTTP/1.1\r\n");

protocal.append( "Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, " +

"image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\r\n");

protocal.append( "Accept-Language: zh-CN\r\n" );

 

//以下的两行最重要

protocal.append(  "Content-Type: multipart/form-data; boundary="+ BOUNDARY + "\r\n" );

protocal.append(  "Content-Length: " + datalength + "\r\n" );

 

protocal.append( "Connection: Keep-Alive\r\n" );

protocal.append(  "Host: " + url.getHost() + ":" + port + "\r\n" );

protocal.append( "\r\n" );

System.out.println("打印一下http头信息:"+   protocal.toString());

//将请求的命令行和请求头信息发出

outputStream.write(   protocal.toString().getBytes());

// 再将文件中的所有的文本类型的普通参数数据都发送出去

outputStream.write(sb2.toString().getBytes());

 

// 将所有文件类型的实体数据发送出去

for (FileProperty fp : files) {

StringBuilder fsb = new StringBuilder();

fsb.append("--");

fsb.append(BOUNDARY);

fsb.append("\r\n");

fsb.append(

"Content-Disposition: form-data; name=\""

+ fp.getParameterName() + "\"; filename=\""

+ fp.getFileName() + "\"").append("\r\n");

fsb.append("Content-Type: " + fp.getContenttype() + "\r\n\r\n");

outputStream.write(fsb.toString().getBytes());

// 发送文件真正的数据

if (fp.getInputStream() != null) { // 是大文件的话,用流输出

byte[] buffer = new byte[2048];

int length = 0;

while ((length = fp.getInputStream().read(buffer, 0, 2048)) != -1) {

outputStream.write(buffer, 0, length);

}

fp.getInputStream().close(); // 关闭输入流

} else { // 是小文件的话,用byte[] data输出

outputStream.write(fp.getData(), 0, fp.getData().length);

}

outputStream.write("\r\n".getBytes());

}

// 最后是发送数据的结束标志,表示数据发送完毕

outputStream.write(ENDLINE.getBytes());

outputStream.flush();

 

// 读取服务器端的回应

BufferedReader read = new BufferedReader(new InputStreamReader(

socket.getInputStream()));

//System.out.println(read.readLine());

if (read.readLine().indexOf("200") == -1) {

return false;

}

outputStream.close();

read.close();

socket.close();

return true;

}

}

 

 

结果验证



 

 



 

 

 

 

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.InputStream;

 

/**

 * 要上传的文件的属性的封装类

 */

public class FileProperty {

private byte[] data;   //要上传的数据,小数据量上传

private InputStream inputStream;  //要上传的数据的输入流,用于大文件上传真

private File file;    //要上传的文件对象

 

private String fileName;  //要上传的文件名

private String parameterName;   //要上传的文件的请求参数名称

private String contenttype="application/octet-stream";

/**

* 此构造方法用于上传一些较小的数据.

* @param filename

* @param data : 只适合存储较少的数据

* @param paramterName

* @param contenttype

*/

public FileProperty(String filename,byte[] data,String paramterName,String contenttype){

this.data=data;

this.fileName=filename;

this.parameterName=paramterName;

if(contenttype!=null){

this.contenttype=contenttype;

}

}

/**

* 可以传较大的文件

* @param filename  文件名

* @param file    要上传的文件

* @param parameterName   文件的参数名字

* @param contenttype     文件类型

*/

public FileProperty(String filename,File file,String parameterName,String contenttype){

this.fileName=filename;

this.parameterName=parameterName;

this.file=file;

try {

this.inputStream=new FileInputStream(file);

} catch (FileNotFoundException e) {

e.printStackTrace();

}

if(contenttype!=null){

this.contenttype=contenttype;

}

}

public byte[] getData() {

return data;

}

public void setData(byte[] data) {

this.data = data;

}

public InputStream getInputStream() {

return inputStream;

}

public void setInputStream(InputStream inputStream) {

this.inputStream = inputStream;

}

public File getFile() {

return file;

}

public void setFile(File file) {

this.file = file;

}

public String getFileName() {

return fileName;

}

public void setFileName(String fileName) {

this.fileName = fileName;

}

public String getParameterName() {

return parameterName;

}

public void setParameterName(String parameterName) {

this.parameterName = parameterName;

}

public String getContenttype() {

return contenttype;

}

public void setContenttype(String contenttype) {

this.contenttype = contenttype;

}

 

 

 

}

 

  • 大小: 152.3 KB
  • 大小: 105.1 KB
0
0
分享到:
评论

相关推荐

    精选_基于Socket编程模拟实现文件的分布式存储_源码打包

    本项目“精选_基于Socket编程模拟实现文件的分布式存储_源码打包”旨在通过Socket编程来实现这样一个系统,使初学者能够理解分布式存储的基本原理并实践相关技术。 首先,Socket编程是网络通信的基础,它允许两个或...

    简单socket文件传输(类似FTP)客户端

    本项目中,客户端通过Socket模拟FTP的行为,允许用户在本地与远程服务器之间传输文件。 3. **断点续传**: 断点续传是文件传输中的一个重要特性,它允许在传输中断后从上次停止的地方继续,而不是重新开始。这在大...

    易语言-易语言基于HPSocket,一键搭建 HTTP 服务,支持POST,GET(开源)

    它是一个基于请求与响应模型的、无状态的、应用层协议。HTTP协议主要包括请求和响应两个部分,其中GET用于信息查询,POST用于数据提交。 POST方法常用于向服务器发送数据,比如表单提交。当用户填写表单并提交时,...

    socket上传文件源码实例,另附带dos进程大爆发巧妙源码

    在这个标题为“socket上传文件源码实例,另附带dos进程大爆发巧妙源码”的资料中,我们可以推测这是一份关于如何使用Socket编程实现文件上传功能的示例代码,同时也包含了一个可能导致Dos(Denial of Service,拒绝...

    struct文件上传功能

    在本实例中,我们关注的是基于C语言结构体(struct)实现的文件上传功能。`struct`在C语言中用于组织数据,它可以让我们自定义数据类型,将多个不同类型的数据组合在一起。在文件上传的场景中,`struct`可能用于存储...

    网口(Socket)调试工具NetAssist

    总结起来,NetAssist作为一款强大的Socket调试工具,为开发者提供了全面的网络通信测试功能,覆盖了TCP和UDP协议,支持环境模拟、定时发送和文件传输等多种场景,而且不受编程语言限制,是网络编程过程中不可或缺的...

    基于java的远程登录和文件传输v

    1. **文件传输协议(FTP)**:FTP是互联网上最广泛使用的文件传输协议,它提供了一种标准方式来上传、下载文件。FTP支持两种模式:ASCII模式(用于文本文件)和二进制模式(用于任何类型的文件)。 2. **FTP的变种*...

    java socket 学习资料

    Java Socket是Java编程语言中用于实现网络通信的核心API,它基于TCP/IP协议栈,提供了低级别的网络连接功能。Socket在Java中被广泛用于构建客户端-服务器应用,例如创建Web服务器、聊天应用程序、文件传输等。以下是...

    FTP 文件传输 基于JAVA的网络编程

    客户端需要模拟FTP命令的发送,如登录服务器、改变目录、列举目录内容、上传和下载文件。Java.io包提供了丰富的输入/输出流类,如`FileInputStream`和`FileOutputStream`,用于本地文件的读写,而`...

    发那科机器人与视觉socket通讯

    3. **Socket通讯**:Socket通讯是一种基于TCP/IP协议的网络通信方式,允许不同计算机上的应用程序之间交换数据。在FANUC机器人与视觉系统的交互中,Socket通讯用于建立和维持两者之间的连接,收发数据,如rece_data....

    linux(基于TX2)实现ftp上传文件到FTP服务器(win10)

    本教程将指导你如何使用C++编程语言通过FTP协议将文件上传到Windows 10上的FTP服务器。FTP(File Transfer Protocol)是一种用于在互联网上进行文件传输的标准协议。 首先,你需要一个支持FTP功能的库。在给定的...

    socket httpclient

    本文将深入探讨基于Socket实现的HttpClient,以及它如何处理GET和POST协议。 首先,Socket是TCP/IP协议族中的一个概念,它提供了一种进程间通信(IPC)机制,允许两台计算机上的应用程序通过网络进行数据交换。在C...

    http1.0 的ftp模拟java实现(含多线程)

    使用Java实现HTTP 1.0的FTP模拟,通常会用到`java.net.Socket`和`java.net.ServerSocket`类来处理客户端和服务器之间的连接,以及`java.io`包中的类来读写文件。 4. **多线程**: 在Java中,多线程可以通过继承`...

    C语言实现ftp文件传输功能ftp.zip

    FTP(File Transfer Protocol)是一种基于TCP/IP协议的网络协议,用于在网络上进行文件传输。C语言实现FTP文件传输功能,涉及到的知识点广泛,包括但不限于网络编程、C语言编程基础、TCP/IP套接字编程以及文件操作等...

    基于c++的模拟爱奇艺web视频上传.zip

    此次学习的是HTTP的post协议,使用使用multipart form-data上传文件。 HTTP1.1封装 简单封装了HTTP1.1的get和post,实现http的长连接模式,实现发送和数据接收。简单实现了socket的复用。 详细介绍参考:...

    计网socket编程实验报告.doc

    首先,实验目的是让学生理解FTP协议的工作原理,并掌握基于Socket的网络编程基础。FTP协议是互联网上广泛使用的文件传输机制,它允许用户从远程服务器上下载文件或将文件上传到服务器。FTP协议主要包括两个主要连接...

    FTP协议实现源代码

    它基于TCP/IP协议栈,设计用于高效地在Internet上传输文件。FTP协议由两部分组成:控制连接和数据连接。控制连接用于发送命令和接收响应,而数据连接则用于实际的数据传输。 在FTP协议中,主要有以下概念: 1. 用户...

    java socket,javasocket教程

    - 基于Socket实现文件的上传和下载功能,通过流传输大文件。 3. **分布式系统** - 在分布式系统中,Socket作为进程间通信的重要手段,常用于协调分布式服务间的通信。 通过上述知识点的学习,开发者可以利用Java...

    模拟 ftp功能

    FTP(File Transfer Protocol)是一种基于TCP协议的网络协议,用于在Internet上进行文件传输。模拟FTP功能意味着我们需要创建一个能够实现FTP基本操作的系统或应用,这些操作包括:get(下载文件)、put(上传文件)...

    基于UDP的LFTP文件传输实验报告1

    本实验报告聚焦于基于UDP的LFTP(Local File Transfer Protocol)文件传输,旨在通过模拟TCP的特性,实现在不可靠的UDP上构建一个可靠的文件传输系统。 LFTP采用了client-server模式,意味着客户端与服务器端之间的...

Global site tag (gtag.js) - Google Analytics