科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道一个关于socket接收post数据的问题

一个关于socket接收post数据的问题

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

一个关于socket接收post数据的问题

作者:csdn 来源:csdn 2009年12月17日

关键字: JavaSE 问答 java

  • 评论
  • 分享微博
  • 分享邮件

一个关于socket接收post数据的问题

写了一个MyServer模拟http server 接收post请求。
java代码:

Java code
package socket; import java.io.*; import java.net.*; public class MyServer { public static void main(String args[]) throws Exception{ ServerSocket serverSocket = new ServerSocket(8080); System.out.println("server is ok."); while(true){ Socket socket = serverSocket.accept(); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); String line = in.readLine(); while(line!=null){ System.out.println("Client: " + line); line = in.readLine(); } System.out.println("current user close the session."); in.close(); socket.close(); } } }



用浏览器打开下面的html文件,并提交数据:

HTML code
<head> <title>test my server</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> </head> <body> <p>upload</p> <form name="UploadForm" method="post" action="http://localhost:8080/1.jsp"> <input type="text" name="myname" /><br> <select name="myage"> <option value="18">18</option> <option value="20">20</option> <option value="22">22</option> </select><br> <input type="submit"value="Sutmit"> </form> </body> </html>


MyServer打印出来的数据开始还正常:
server is ok.
Client: POST /testupload.jsp HTTP/1.1
Client: Accept: image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Client: Referer: http://localhost:8080/post.html
Client: Accept-Language: zh-cn
Client: User-Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)
Client: Content-Type: application/x-www-form-urlencoded
Client: Accept-Encoding: gzip, deflate
Client: Host: localhost:8080
Client: Content-Length: 28
Client: Connection: Keep-Alive
Client: Cache-Control: no-cache
Client:
走到这里的时候, 按http协议,接下来浏览器该传送post的数据了,但是程序走到这里就不走了。当我按esc之后,post数据才被提交上去
Client: myname=wwwwwwwwwwww&myage=18
current user close the session.

 

有两个问题:

1、因为你是readLine,最后的数据并没有回车换行,所以readLine就一直悬停了,你可以改成read(char[])这个方法试试,就能读到数据
2、你在读到数据后,应该向客户端发出应答,否则客户端不会关闭Socket(除非超时,可能很长),这样你的程序还是会挂在那里不退出。

有两个问题:

1、因为你是readLine,最后的数据并没有回车换行,所以readLine就一直悬停了,你可以改成read(char[])这个方法试试,就能读到数据
2、你在读到数据后,应该向客户端发出应答,否则客户端不会关闭Socket(除非超时,可能很长),这样你的程序还是会挂在那里不退出。
 

并不奇怪,
readline要到文本行结尾才返回,
但post提交的数据通过http消息体发送,末尾不必加换车符,
所以此时readline就卡在那里了。
空行是http头和消息体的分隔,
可以在读到空行后,退出循环,转而用普通的读字符方式处理。

 

这样不行,因为-1代表流结束,而如果服务端不向客户端发送应答,流是不会结束的。
答:楼主只要客户端发的数据能够一下子全显示出来,而不是readLine()那样显示不全就停止在那儿。这与“流是不会结束的”是没有关系的。只要数据能够一下子全显示出来,楼主的目的就达到了。
关于流结束的问题,那是一个长连接,双方按HTTP协议来交互就行了[需要楼主解析HTTP头部内容],没有什么奥秘的。

 

1)对socket流的用法不是很规范。原因是:每一个socket,关联一个输入流及输出流,
当楼主转换成BufferedReader后,应将该br流传输到任何要用的方法中,而不是每一个方法中去分别创建流。
2)就是要在方法中分别创建流(像现在这种情形:在service()方法中创建一个socket对应
的br流,在doPost()方法中对同一个socket,再创建一个socket对应的br流),又怎么样呢?
这就会出现楼主现在遇到的这种情况:好像读不到数据了。其真正的原因是什么?
是这样:
每一个方法中所创建的br流,其底层是同一个InputStream流,当我们在service()方法中创建br流时[其实只要创建InputStreamReader流时],由于这些流内部都是有缓冲的,因而,一旦在service()方法中发生了读操作,立即会导致底层InputStream读入大量数据。[内部缓冲是8K],这时我们在doPost()方法中再创建br进行读取时,已被service()方法中读走
的数据[8K],在doPost()中再也读不到了已被读走的数据。[只能读它之后的数据]这就是困绕楼主看到的情况[误认为:好像是读不到数据了。]。对于情况,用mark()与reset()
是没有用的--它只对br流有用,但是:[因为底层InputStreamReader中使用了StreamDecoder,它有默认8K的BUF缓冲]。因此:
结论:[怎么办?]
1)若在service()中,创建了br流,但没有发生读操作,则此时doPost()中再创建br流读取,将一切正常。
2)若在service()中,不创建任何底层内部带缓冲的流,直接使用原始的socket的InputStream进行
读操作,则此时doPost()中再创建br流读取,也将一切正常。
3)若在service()中,创建任何底层内部带缓冲的流,即使使用mark()与reset(),因为它只是对内部带缓冲的流起作用,而不是对socket的InputStream起作用,一旦已发生读操作,则此时doPost()中再创建br流读取,将再也读不到了已被读走的数据。就会出现楼主现在遇到的这种情况:好像在doPost()读不到数据了。[其实不是,而是本来数据不多,
已全被读走了。]
4)规范的用法:一旦有了socket,创建它的I/O流,将该流传入到所有需要的方法中,而不是
每一个方法都自己来再创建流。

 

确实是这样,处理HTTP头,需要字符流,但处理数据部分,需要字节流,怎么办?
实际上,HTTP协议是建立在字节流基础之上的。即:HTTP协议明确规定每一行是以CRLF结束的(即ACSII码13与ACSII码10)。因此:我想:可能的话,还是以字节流统一处理HTTP头部[因为:只有ASCII字符,不会有汉字的]。这样做的目的是:处理HTTP BODY部分时,只能是字节流。,因而HTTP头部与HTTP BODY就可以统一处理了。为什么在处理HTTP头部时,不能用BufferedReader来处理?还是那个缓冲问题。[它会把BODY部分的字节数据以字符流方式预先读入进来,这就会造成:以字符流方式处理字节流的HTTP BODY,可能会有问题]。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章