关于socket的readLine和read问题

本文分析了在Socket编程中,针对浏览器客户端的POST和GET请求,服务器端使用readLine()和read()方法的不同行为。readLine()在遇到不同请求类型时可能导致阻塞或丢失信息,而read()则能确保读取完整请求信息,但多次调用可能引发阻塞问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、背景:客户端为浏览器,服务端自己编写
二、浏览器请求信息两种(这里以post/get举例):

POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Content-Length: 41
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: null
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
RA-Ver: 2.10.4
RA-Sid: 7ABC76C3-20150513-021418-fef719-00a78b
(换行符)
(换行符)uname=%BB%F4%B2%BC%CB%B9sf&pwd=dsaf&fav=0
GET /favicon.ico HTTP/1.1
Host: localhost:8888
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: zh-CN,zh;q=0.8
RA-Ver: 2.10.4
RA-Sid: 7ABC76C3-20150513-021418-fef719-00a78b
(换行符)
(换行符)

ps:浏览器发完这些信息后,服务器会等待浏览器的进一步信息

三、分析
1.关于readLine
①接收代码为!=null的情况:

BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String msg = null;
StringBuffer sb = new StringBuffer();
    while(null!=(msg=br.readLine())){
        sb.append(msg);
        sb.append("\r\n");
    }

分析:这种代码,不管浏览器请求方法是post还是get,服务器在接收完请求信息后,会阻塞在readLine方法这里,等待浏览器 进一步的信息,所以程序不会走下去,也就是不会执行下面的代码。即程序在readLine这里阻塞,不会继续执行下面的代码
②接收代码为>0的情况

BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));
String msg = null;
StringBuffer sb = new StringBuffer();
    while((msg=br.readLine()).length()>0){
        sb.append(msg);
        sb.append("\r\n");
    }

分析:
<1>当浏览器请求信息是Post方法时,readLine读到参数前面时,会读到一个空字符串,即长度为零,跳出循环,执行下面代码。即丢失了参数信息,会执行下面的代码
<2>当浏览器请求信息是get方法时,readLine会读到请求信息最后一个换行符前面的空字符串,即长度为零,跳出循环,执行下面代码。即读出的是完整信息,会执行下面的代码

2.关于read
服务器接收代码如下:

BufferedInputStream bs = new BufferedInputStream(client.getInputStream());
byte[] data = new byte[20480];
//读取信息
int len = bs.read(data);
String requestInfo = new String(data,0,len).trim();

分析:不管请求信息是post方法还是get方法,服务器20480个字节足够读到完整请求信息,然后继续执行下面的代码。即读出的是完整信息,会执行下面的代码

(PS:关于阻塞问题,有人误认为程序会在read(data)这里阻塞,这种理解是错误的。正确的理解是:read(data)为服务器的第一次读取数据,读到了请求信息的数据,返回请求信息的数据字节长度。如果再用read(data)读一次,刚由于前面请求信息已经读完,现在读不到数据了,从而发生阻塞问题,不会继续执行下面代码)


总结:略
(不会总结,有需要的自己总结吧)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值