`
kingj
  • 浏览: 425690 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

java socket发送http

 
阅读更多

含义 ENCTYPE="multipart/form-data" 说明: 
通过 http 协议上传文件 rfc1867协议概述,jsp 应用举例,客户端发送内容构造 

1、 概述在最初的 http 协议中,没有上传文件方面的功能。 rfc1867 (http://www.ietf.org/rfc/rfc1867.txt) 为 http 协议添加了这个功能。客户端的浏览器,如 Microsoft IE, Mozila, Opera 等,按照此规范将用户指定的文件发送到服务器。服务器端的网页程序,如 php, asp, jsp 等,可以按照此规范,解析出用户发送来的文件。Microsoft IE, Mozila, Opera 已经支持此协议,在网页中使用一个特殊的 form 就可以发送文件。绝大部分 http server ,包括 tomcat ,已经支持此协议,可接受发送来的文件。各种网页程序,如 php, asp, jsp 中,对于上传文件已经做了很好的封装。 

2、上传文件的实例:用 servelet 实现(http server 为 tomcat 4.1.24)1. 在一个 html 网页中,写一个如下的form :

<form enctype="multipart/form-data" action="http://192.168.29.65/UploadFile" method=post>  
load multi files :<br>    
<input name="userfile1" type="file"><br>   
<input name="userfile2" type="file"><br> 
<input name="userfile3" type="file"><br>    <input name="userfile4" type="file"><br>   
text field :<input type="text" name="text" value="text"><br>   
<input type="submit" value="提交"><input type=reset></form> 



用户可以选择多个文件,填写表单其它项,点击“提交”按钮后就开始上传给 http://192.168.29.65/upload_file/UploadFile 

这 是一个 servelet 程序注意 enctype="multipart/form-data", method=post, type="file" 。根据 rfc1867, 这三个属性是必须的。multipart/form-data 是新增的编码类型,以提高二进制文件的传输效率。具体的解释请参阅 rfc18672. 服务端 servelet 的编写现在第三方的 http upload file 工具库很多。Jarkata 项目本身就提供了fileupload 包http://jakarta.apache.org/commons/fileupload/ 。 

文件上传、表单项处理、效率问题 基本上都考虑到了。在 Struts 中就使用了这个包,不过是用 Struts 的方式另行封装了一次。这里我们直接使用 fileupload 包。至于Struts 中的用法,请参阅 Struts 相关文档。这个处理文件上传的 servelet 主要代码如下: 

public void doPost( HttpServletRequest request, HttpServletResponse response ) 
{   
    DiskFileUpload diskFileUpload = new DiskFileUpload();    // 允许文件最大长度 
    diskFileUpload.setSizeMax( 100*1024*1024 );    // 设置内存缓冲大小 
    diskFileUpload.setSizeThreshold( 4096 );    // 设置临时目录   
    diskFileUpload.setRepositoryPath( "c:/tmp" );  
    List fileItems = diskFileUpload.parseRequest( request );  
    Iterator iter = fileItems.iterator();    for( ; iter.hasNext(); ) 
    {    
    FileItem fileItem = (FileItem) iter.next();   
      if( fileItem.isFormField() ) {         // 当前是一个表单项    
    out.println( "form field : " + fileItem.getFieldName() + ", " + fileItem.getString() );    
      } else {       
    // 当前是一个上传的文件       
    String fileName = fileItem.getName();  
    fileItem.write( new File("c:/uploads/"+fileName) );     
      }  

}} 



为 简略起见,异常处理,文件重命名等细节没有写出。3、 客户端发送内容构造假设接受文件的网页程序位于 http://192.168.29.65/upload_file/UploadFile.假设我们要发送一个二进制文件、一个文本框表单项、一个密码 框表单项。文件名为 E:\s ,其内容如下:(其中的XXX代表二进制数据,如 01 02 03)abbXXXccc 客户端应该向 192.168.29.65 发送如下内容: 


POST /upload_file/UploadFile HTTP/1.1 
Accept: text/plain, */* 
Accept-Language: zh-cn 
Host: 192.168.29.65:80 
Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6 
User-Agent: Mozilla/4.0 (compatible; OpenOffice.org) 
Content-Length: 424 
Connection: Keep-Alive -----------------------------7d33a816d302b6 
Content-Disposition:form-data; 
name="userfile1"; 
filename="E:\s"Content-Type: 
application/octet-stream abbXXXccc 
-----------------------------7d33a816d302b6 

Content-Disposition: form-data; 

name="text1" foo 

-----------------------------7d33a816d302b6 

Content-Disposition: form-data; 

name="password1" bar 

-----------------------------7d33a816d302b6-- 


(上面有一个回车)此内容必须一字不差,包括最后的回车。 

注意:Content-Length: 424 这里的424是红色内容的总长度(包括最后的回车) 
注意这一行:Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6 

根据 rfc1867, multipart/form-data是必须的.---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。 

其中33a816d302b6 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的 ---------------------------7d 是 IE 特有的标志。 

Mozila 为---------------------------71用手工发送这个例子,在上述的 servlet 中检验通过。 




使用POST发送数据 

   以POST方式发送数据主要是为了向服务器发送较大量的客户端的数据,它不受URL的长度限制。POST请求将数据以URL编码的形式放在HTTP正文 中,字段形式为fieldname=value,用&分隔每个字段。注意所有的字段都被作为字符串处理。实际上我们要做的就是模拟浏览器POST 一个表单。以下是IE发送一个登陆表单的POST请求: 

POST http://127.0.0.1/login.do HTTP/1.0 
Accept: image/gif, image/jpeg, image/pjpeg, */* 
Accept-Language: en-us,zh-cn;q=0.5 
Content-Type: application/x-www-form-urlencoded 
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) 
Content-Length: 28 
\r\n 
username=admin&password=1234 


  要在MIDP应用程序中模拟浏览器发送这个POST请求,首先设置HttpConnection的请求方式为POST: 

hc.setRequestMethod(HttpConnection.POST); 


  然后构造出HTTP正文: 

byte[] data = "username=admin&password=1234".getBytes(); 

  并计算正文长度,填入Content-Type和Content-Length: 

hc.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); 
hc.setRequestProperty("Content-Length", String.valueOf(data.length)); 

  然后打开OutputStream将正文写入: 

OutputStream output = hc.openOutputStream(); 
output.write(data); 


   需要注意的是,数据仍需要以URL编码格式编码,由于MIDP库中没有J2SE中与之对应的URLEncoder类,因此,需要自己动手编写这个 encode()方法,可以参考java.net.URLEncoder.java的源码。剩下的便是读取服务器响应,代码与GET一致,这里就不再详 述。 

  使用multipart/form-data发送文件 

  如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。 

  以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD: 

hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD"); 

  然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件C:\1.txt,HTTP正文如下: 

--ABCD 
Content-Disposition: form-data; name="title" 
\r\n 
Today 
--ABCD 
Content-Disposition: form-data; name="1.txt"; filename="C:\1.txt" 
Content-Type: text/plain 
\r\n 
<这里是1.txt文件的内容> 
--ABCD-- 
\r\n 


   请注意,每一行都必须以\r\n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于 ---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器 无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。 

  发送文件的POST代码如下: 

String[] props = ... // 字段名 
String[] values = ... // 字段值 
byte[] file = ... // 文件内容 
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符 
StringBuffer sb = new StringBuffer(); 
// 发送每个字段: 
for(int i=0; i 
sb = sb.append("--"); 
sb = sb.append(BOUNDARY); 
sb = sb.append("\r\n"); 
sb = sb.append("Content-Disposition: form-data; name=\""+ props[i] + "\"\r\n\r\n"); 
sb = sb.append(URLEncoder.encode(values[i])); 
sb = sb.append("\r\n"); 

// 发送文件: 
sb = sb.append("--"); 
sb = sb.append(BOUNDARY); 
sb = sb.append("\r\n"); 
sb = sb.append("Content-Disposition: form-data; name=\"1\"; filename=\"1.txt\"\r\n"); 
sb = sb.append("Content-Type: application/octet-stream\r\n\r\n"); 
byte[] data = sb.toString().getBytes(); 
byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); 
// 设置HTTP头: 
hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY); 
hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length)); 
// 输出: 
output = hc.openOutputStream(); 
output.write(data); 
output.write(file); 
output.write(end_data); 
// 读取服务器响应: 
// TODO...

 

 

 

 

 

 

 

 

 

 

 

总结常用的GET,POST,POST(FILE)的http头信息

GET的运行结果演示

GET/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows ;U;WindowsNT 5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+XML ,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=1&password=2

  普通POST的结果演示

POST/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows ;U;WindowsNT5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=111&password=222
Content-Type:application/x-www-form-urlencoded
Content-Length:25
username=111&password=222

  POST文件上传的结果演示

POST/?username=111&password=222HTTP/1.1
Host:127.0.0.1:8000
User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:1.9.0.1)Gecko/2008070208Firefox/3.0.1
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language:zh-cn,zh;q=0.5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0.7,*;q=0.7
Keep-Alive:300
Connection:keep-alive
Referer:http://127.0.0.1:8000/?username=111&password=222
Content-Type:multipart/form-data;boundary=---------------------------23757983230932
Content-Length:1704
-----------------------------23757983230932
Content-Disposition:form-data;name="phototitle"
12
-----------------------------23757983230932
Content-Disposition:form-data;name="photo";filename="技术考核题.txt"
Content-Type:text/plain
技术考核
本次是个编程题,题目选Java /语言进行回答。
问题描述:
假设你的爱好是集邮。目前总共有N种不同的邮票,编号为从0到N-1.每种邮票的价钱被定义在数组int[]prices中(序号从0开始,数组的第i个元素表示第i种邮票的价格)。
你的目标是收集尽可能多种的邮票。你当前拥有的邮票存储在int[]have这个数组中。初始时,你没有钱,但是你可以卖掉已有邮票来买不同的邮票。返回你能收集到的不同种邮票的最大数量。
定义:
class:PostmarksCollection
method:numberOfDistinctPostmarks
Parameters:int[],int[]
Returns:int
Methodsignature:publicintnumberOfDistinctPostmarks(int[]prices,int[]have)
//为了进行测试,必须保证是public
约束:
1)N从1到50
2)prices中的元素数量刚好是N个元素
3)prices中的元素的值,从1到1,000,000
4)have中的元素数量是0个到N个
5)have中的每个元素是不同的
6)have中的每个元素的值是从0到N-1.
例如:
1)
{13,10,14,20}
{3,0,2,1}
Returns:4
你已经拥有所有种类的邮票。
2)
{7,5,9,7}
{}
Returns:0
你开始没有任何邮票,所以你也不能组任何事情。
3)
{4,13,9,1,5}
{1,3,2}
Returns:4
卖掉邮票2,买入邮票0和4,(邮票2的价钱是9,邮票0的价钱是4,邮票4的价钱是5,卖掉2刚好买入0和4)
4)
{16,32,13,2,17,10,8,8,20,17}
{7,0,4,1,6,8}
Returns:8
--------------------------------------------------------------------------------
使用Java请在此处答题(请使用JDK 5.0编译,编译不能通过者不计算分数)
-----------------------------23757983230932--

分享到:
评论

相关推荐

    java socket 发送http请求webservice.

    Java Socket 发送HTTP请求Web Service是一项...总的来说,Java Socket发送HTTP请求Web Service涉及网络编程和HTTP协议的理解,通过源码实现可以深入学习底层原理,但实际项目中可能更倾向于使用成熟的HTTP客户端库。

    利用java socket实现发送http请求

    基于java socket发送http请求。这种原生的发送请求的方式能适合一些特定场景,比如: A向B发送请求,A不考虑B是否处理成功,即A不关注B的响应结果,那么A就不用阻塞等B的回应。 传统的Httpclient请求方式都是阻塞...

    JAVA Socket编程实现文件上传

    在这个场景中,我们讨论的是如何使用Java的Socket来实现文件上传功能,即从客户端将文件发送到服务器,然后保存到服务器的数据库中。这个过程涉及到多个关键知识点,下面我们将详细探讨。 1. **Java Socket基础**:...

    java socket 学习资料

    - `HttpURLConnection`是Java标准库中的类,可方便地发送HTTP请求(GET、POST等)。 - 对于简单的HTTP操作,`HttpURLConnection`可能比直接使用Socket更简洁,但自定义性较差。 7. **异常处理**: - Java Socket...

    Java Socket 实用教程

    `Socket.getInputStream()`返回一个`InputStream`用于读取数据,`Socket.getOutputStream()`返回一个`OutputStream`用于发送数据。 4. **异常处理**:网络通信中常见的异常有`IOException`,如连接超时、网络中断等...

    一个简单的java socket程序

    学习这个简单的Java Socket程序,可以让你了解网络通信的基本原理,为进一步的网络编程,如HTTP、FTP等协议的实现打下基础。同时,也可以帮助你掌握Java的IO流操作,这对于处理任何类型的数据传输都是非常重要的。

    Java Socket PC端传输文件简易服务器客户端

    在Socket通信中,我们通常会将文件内容封装成字节流,然后通过Socket发送。 4. **套接字输入/输出流(SocketInputStream/SocketOutputStream)**: - Socket类提供了与之相关的输入流和输出流,用于在网络中进行...

    Java实现Socket长连接和短连接

    在Java编程中,Socket是网络通信的基础,它允许两个应用程序通过TCP/IP协议进行数据传输。Socket连接分为两种类型:长连接和短连接。这两种连接方式各有特点,适用于不同的应用场景。 **1. 短连接(Short ...

    java socket

    Java Socket是Java编程语言中用于网络通信的核心API,它提供了低级别的、面向连接的、基于TCP/IP的通信机制。在Java中,Socket是基于TCP(传输控制协议)的,为应用程序提供了一种可靠的、双向的通信方式。通过...

    java socket 聊天室

    虽然Java Socket是基于TCP/IP协议的,但实际的聊天室应用可能还涉及到其他协议,如HTTP、FTP等,具体取决于项目的复杂性和需求。 以上就是基于Java Socket实现的聊天室所涉及的主要技术点,这个项目对于学习网络...

    Java Socket实现简单的web服务器

    5. **HTTP 响应**: 服务器需要构建并发送HTTP响应给客户端。响应包括状态行(例如`HTTP/1.1 200 OK`,表示成功),响应头(如`Content-Type: text/html`定义资源类型),以及响应体(即实际的文件内容)。 6. **多...

    java http 发送xml报文

    在IT领域,尤其是在Java开发中,通过HTTP协议发送XML报文是一种常见的数据交换方式,尤其在与Web服务交互时。本文将深入解析如何利用Java语言实现HTTP请求,并发送XML格式的数据,同时也会涵盖相关的概念、代码解读...

    JAVA使用Socket编写HTTP服务器

    在Java编程语言中,使用Socket实现一个简单的HTTP服务器是一项基础但重要的技能。HTTP服务器是互联网上用于接收HTTP请求并返回响应的程序。本教程将详细解释如何通过Socket类来构建这样的服务器,同时会涉及到相关的...

    用java写socket.io客户端所需jar包

    - 连接到服务器:`Socket socket = IO.socket("http://your-server-url:port");` - 注册事件监听器:例如,`socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {...});` 用于监听连接成功事件。 - 发送和...

    Java Socket源码

    - Java Socket遵循TCP/IP协议栈,包括IP、TCP、应用层协议(如HTTP、FTP等)。理解这些协议有助于理解Socket的工作机制。 - 协议文档提供了Socket通信的具体规则,如报文格式、连接建立和关闭的流程等。 7. **...

    HTTP-and-Socket.rar_http socket_java socket http_socket_socket

    1. **Java HTTP客户端**:Java内置的HttpURLConnection或第三方库如Apache HttpClient可以用来发送HTTP请求和处理响应。 2. **Java Socket编程**:使用java.net.Socket和ServerSocket类,可以构建TCP Socket通信。...

    java socket 编程,Java socket 编程实例

    ### Java Socket编程详解及实例分析 #### 一、Socket编程基础概述 在计算机网络通信领域,Socket编程是一种广泛使用的通信方式。它为不同主机上的进程提供了双向通信的能力,是网络编程的基础之一。Java语言提供了...

    Java_Socket现实简单的HTTP服务

    2. **接收请求**:一旦客户端连接,服务器将通过`java.net.Socket`对象读取客户端发送的HTTP请求。 3. **解析请求**:分析请求中的方法(如GET或POST)、URL及HTTP版本,同时识别任何头部信息。 4. **生成响应**:...

    Java Socket 编程html教程

    8. **实例应用**:例如,你可以创建一个简单的聊天服务器,客户端通过Socket发送消息到服务器,服务器再广播给所有连接的客户端。HTML则用于显示聊天历史和输入新消息的表单。 9. **HTTP协议**:虽然本文主要讨论...

    Java Socket编程实现的简单多线程WEB服务器

    Java Socket 编程实现的简单多线程 WEB 服务器 在本文中,我们将详细介绍如何使用 Java 的 Socket 编程实现一个简单的多线程 WEB 服务器。 Socket 编程简介 Socket 编程是 Java 网络编程的基础,它允许开发者创建...

Global site tag (gtag.js) - Google Analytics