tcp ip http socket udp
先来一个讲TCP、UDP和HTTP
1、TCP/IP是个协议组,可分为三个层次:网络层、传输层和应用层。
在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。
在传输层中有TCP协议与UDP协议。
在应用层有FTP、HTTP、TELNET、SMTP、DNS等协议。
因此,HTTP本身就是一个协议,是从Web服务器传输超文本到本地浏览器的传送协议。
2、HTTP协议是建立在请求/响应模型上的。首先由客户建立一条与服务器的TCP链接,并发送一个请求到服务器,请求中包含请求方法、URI、协议版本以及相关的MIME样式的消息。服务器响应一个状态行,包含消息的协议版本、一个成功和失败码以及相关的MIME式样的消息。
HTTP/1.0为每一次HTTP的请求/响应建立一条新的TCP链接,因此一个包含HTML内容和图片的页面将需要建立多次的短期的TCP链接。一次TCP链接的建立将需要3次握手。
另外,为了获得适当的传输速度,则需要TCP花费额外的回路链接时间(RTT)。每一次链接的建立需要这种经常性的开销,而其并不带有实际有用的数据,只是保证链接的可靠性,因此HTTP/1.1提出了可持续链接的实现方法。HTTP/1.1将只建立一次TCP的链接而重复地使用它传输一系列的请求/响应消息,因此减少了链接建立的次数和经常性的链接开销。
3、结论:虽然HTTP本身是一个协议,但其最终还是基于TCP的。不过,目前,有人正在研究基于TCP+UDP混合的HTTP协议。
Socket是什么呢?
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。
这是从大的概况上描述了一下相互关系,还有一些重要的细节需要进一步了解,很多时候,这些细节才更重要。
我们将按这样的顺序讨论:
- http,tcp, upd,socket等,最终目的是用于通信,所以设计这些协议或者接口的时候,肯定会涉及通信机制,那么“三次握手”是啥,为何是"三次握手“,两次或四次可以?
- 实现是落实到httpConnectClient,需要设置那些参数呢。
- http1.0和http1.1有啥不同。
- 我们在服务器上经常看到tcp的一些状态是TIME_WAIT是啥意思,还有那些状态。
-
为何三次握手?
至于什么是三次握手,则可以参考各种文档,三次握手。可以用一张图来看一下:
三次握手的起因:
通信最主要的是信道的安全,那就是c和s通信,c要确保s的真实存在; s也要包装c的真实存在。
那就好了: c如何保证s真实存在? 发j,必须返回k,和j+1; 这样就验证了;
那么s也需要包装s的真实存在,同样原理:过去的k,必须应答k+1,否则无法正常建立。当然,加密通信时,进一步提高安全性。这只是最小代价的验证方式,但并不是绝对安全。
更为合理的解释:
这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足"在不可靠信道上可靠地传输信息"这一需求所导致的. 请注意这里的本质需求,信道不可靠, 数据传输要可靠. 三次达到了, 那后面你想接着握手也好, 发数据也好, 跟进行可靠信息传输的需求就没关系了.因为验证信道安全的事情已经结束,但理论上是无法绝对安全的,因为验证的总是当前的状态,下一刻也许被攻击或者失去联系(比如服务器掉电,战争中的电报机突然被炸毁)。
因此,如果信道是可靠的, 即无论什么时候发出消息, 对方一定能收到, 或者你不关心是否要保证对方收到你的消息, 那就能像UDP那样直接发送消息就可以了.”。这可视为对“三次握手”目的的另一种解答思路。
假设是2次握手会发生什么?
C发送请求,S应答并分配资源 ;
一旦S的应答没有到达C端,C认为连接未建立,而S认为建立了
S会在一段时间内保留分配的资源
如果大量C这样请求,S会崩溃。
如果是四次握手呢?
其实以后可以无限次的握手,是更加安全的验证通道,最终还是为了传输”数据“,这是一种”安全性“和”代价“的平衡策略。为了安全,你可以验证四次,甚至五次,只是这增加了成本,相对提高了一些信道安全的验证。
注:那张图我写成了”四次握手“,其实是错的,应该是四次挥手。
- httpConnectClient的实现
1 String currentUrl=“http://www.cnblogs.com/notech”; //URL ?后面的内容为HTTP请求的正文URL url = new URL(currentUrl);
2
3 HttpURLConnection httpurlconnection = url.openConnection();//下面的设置对应HTTP请求中的消息报头
4 httpurlconnection.setRequestProperty("User-Agent",CommonValues.User_Agent);
5 httpurlconnection.setRequestProperty("Accept",CommonValues.Accept);
6 httpurlconnection.setRequestProperty("Accept-Charset",CommonValues.Accept_Charset);
7 httpurlconnection.setRequestProperty("Accept-Language",CommonValues.Accept_Language);
8 httpurlconnection.setRequestProperty("Connection",CommonValues.Connection);
9 httpurlconnection.setRequestProperty("Keep-Alive",CommonValues.Keep_Alive);
10 httpurlconnection.setConnectTimeout(CommonValues.ConnectionTimeOut);
11 httpurlconnection.setReadTimeout(CommonValues.ReadTimeOut);
12
13 httpurlconnection.connect();
14
15 int responsecode = httpurlconnection.getResponseCode();
16
17 if(responsecode == HttpURLConnection.HTTP_OK) //对应HTTP响应中状态行的响应码{
18 //操作请求流,这里对应HTTP响应中的响应正文
19 }
20
21 if (httpurlconnection != null)
22 {
23 httpurlconnection.disconnect();
24 }
更多的参数可以参考官方文档:也就是http协议的官方文档。
http://www.w3.org/Protocols/rfc2616/rfc2616.html
-
http1.0和http1.1区别?
刚才提到了,一个重要的则是长连接的建立,提高网络使用率。当然更为全面的区别,可以参考一篇论文。更加全面。
Key Differences between HTTP/1.0 and HTTP/1.1
如果因为国内限制访问很多国外ip,我拷贝一段重要的:
We structure our discussion by (somewhat arbitrarily) dividing the protocol changes into nine major areas:
1.
Extensibility
2.
Caching
3.
Bandwidth optimization
4.
Network connection management
5.
Message transmission
6.
Internet address conservation
7.
Error notification
8.
Security, integrity, and authentication
9.
Content negotiation
-
tcp状态,TIME_WAIT?
通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。
客户端主动关闭连接时,会发送最后一个ack后,然后会进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释),进入CLOSED状态。
使用netstat –an命令会看到很多TIME_WAIT的TCP链接。
更多:
LISTEN:(Listening for a connection.) |
侦听来自远方的TCP端口的连接请求 |
SYN-SENT:(Active; sent SYN. Waiting for a matching connection request after having sent a connection request. |
再发送连接请求后等待匹配的连接请求 |
SYN-RECEIVED:(Sent and received SYN. Waiting for a confirming connection request acknowledgment after having both received and sent connection requests.) |
再收到和发送一个连接请求后等待对方对连接请求的确认 |
ESTABLISHED:(Connection established.) |
代表一个打开的连接 |
FIN-WAIT-1:(Closed; sent FIN.) |
等待远程TCP连接中断请求,或先前的连接中断请求的确认 |
FIN-WAIT-2:(Closed; FIN is acknowledged; awaiting FIN.) |
从远程TCP等待连接中断请求 |
CLOSE-WAIT:(Received FIN; waiting to receive CLOSE.) |
等待从本地用户发来的连接中断请求 |
CLOSING:(Closed; exchanged FIN; waiting for FIN.) |
等待远程TCP对连接中断的确认 |
LAST-ACK:(Received FIN and CLOSE; waiting for FIN ACK.) |
等待原来的发向远程TCP的连接中断请求的确认 |
TIME-WAIT:(In 2 MSL (twice the maximum segment length) quiet wait after close. ) |
等待足够的时间以确保远程TCP接收到连接中断请求的确认 |
CLOSED:(Connection is closed.) |
没有任何连接状态 |
- http的keep-alive?
我们知道HTTP协议采用“请求-应答”模式,当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成 之后立即断开连接(HTTP协议为无连接的协议);当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服 务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。
http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive",才能启用Keep-Alive;http 1.1中默认启用Keep-Alive,如果加入"Connection: close ",才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况。
有人会问,time一般多少时间?
Keepalive messages were not officially supported in HTTP 1.0. In HTTP 1.1 all connections are considered persistent, unless declared otherwise[1]. However, the default keepalive timeout of Apache 2.0 httpd is as little as 15 seconds] and for Apache 2.2 only 5 seconds. The advantage of a short timeout is the ability to deliver multiple components of a web page quickly while not tying up multiple server processes or threads for too long.
当然tcp也有keepalive,不过只是验证tcp是否存活,和http的keepalive不是一回事,详细的可以参考下面的文档:
零零碎碎整理了一些,有些细节还需继续深入,并把理论和实践(代码)相结合,最好结合官方文档。防止误解和遗漏。
一些参考文章:
- http://blog.csdn.net/jzhf2012/article/details/8886633 http头信息参数等
- http://www.cnblogs.com/cswuyg/p/3653263.html
- http://www.cnblogs.com/anee/p/3269982.html
- http://en.wikipedia.org/wiki/Two_Generals%27_Problem
- http://stackoverflow.com/questions/9334401/http-keep-alive-and-tcp-keep-alive