Chinaunix首页 | 论坛 | 博客
  • 博客访问: 670936
  • 博文数量: 81
  • 博客积分: 1659
  • 博客等级: 上尉
  • 技术积分: 1286
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-02 16:36
个人简介

专注于嵌入式和图像处理

文章分类

全部博文(81)

文章存档

2014年(1)

2013年(7)

2012年(46)

2011年(27)

分类: C/C++

2013-09-13 10:24:24


  1. void Sift(A[],int n,int k)
  2. {
  3.     int i = k;
  4.     int j = 2*i;
  5.     while(j<n)
  6.     {
  7.         if(A[j]<A[i]) //左子树
  8.         {
  9.             int temp = A[j];
  10.             A[j] = A[i];
  11.             A[i] = temp;
  12.             i = j;
  13.             j = 2*i;
  14.         }
  15.         
  16.     }
  17. }

整个过程可简述为如下五步:

  服务器端,通过调用socketbindlisten等待客户端的连接。

  客户端调用socket后,调用connect主动连接,它向服务器发送一个连接请 求报文段,该报文段中TCP首部中的同步位SYN(Synchronize)=1,同时选择 一个初始序列号seq=J,一般来说,SYN连接请求报文段不携带数据,只包 含一个IP头部、TCP头部及可能有的TCP选项信息。但是,它要消耗一个 序列号。然后客户端进程进入SYN_SENT(同步已发送)状态。

  服务器端进程接收到客户端的SYN连接请求报文段后,它向客户端发送一 个确认报文段,该报文段中TCP首部中的同步位SYN和确认位ACK都为1 确认号ack=J+1(表示J报文段已经收到,下次要接收的报文段序号为J+1) 同时它也要选择一个初始序列号seq=K,同样该报文段一般也不携带数据, 要消耗一个序列号。此时服务器端进程进入SYN_RECV(同步收到)状态。

  客户端收到服务端确认报文段后,它再想客户端发送一个确认报文段,该报 文段中ACK位为1,确认号ack=K+1,该报文段序列号seq=J+1TCP标准 规定,该报文段可以携带数据,但若不携带数据则不消耗序列号,即此时, 下一个报文段序列号还是J+1,这是客户端进入ESTABLISHLED(已建立连 )状态。

  服务器端收到客户端的确认后,也进入ESTABLISHLED状态。

1111111

sshot-2

好了,对于上面的分析我们告一段落,现在再来讨论一个问题,也是面试的时候,经常会被问到的.

问题1:假如第三次客户端向服务器端发送的ACK的丢失,会出现什么情况?

问题分析:第三次客户端向服务器端发送的ACK丢失,此时客户端处于ESTABLISHLED状态,但服务器端处于SYN_RECV状态。此时可能会出现两种情况:

(1) 因为客户端处于ESTABLISHLED状态,所以它认为连接已经建立了可以发送数据了,此时如果它发送数据给服务端,但是由于服务端没有接收到ACK,它还处于SYN_RECV状态,这个时候服务器端接收到客户端发来的数据,将回应RST报文,告之Server端错误。

(2) 对于Server端,它在一段时间内没有接收到ACK报文,它将重新发送SYN+ACK报文段,以便Client端再次发送ACK报文。

问题2TCP建立连接的时候,为什么非要用三次握手,而只用两次可以吗?

问题分析:问题意思就是说,不用第三次客户端发给服务端的ACK确认报文,即当服务器端接收到客户端的SYN报文时,服务器端就进入ESTABLISHLED状态,然后向客户端发送SYN+ACK报文,当客户端接收到该报文时,客户端也进入ESTABLISHLED状态。然后两种就可以发送数据了。咋一看,这样似乎没有问题,但是假如服务端向客户端发送的SYN+ACK报文丢失,会出现什么情况?此时Server端进入ESTABLISHLED状态,值得注意的是,进入这个状态,代表该端认为连接建立成功,它就会分配资源,以为接下来数据传输做准备。对于Client端,由于它没有接收到ACK,它会以为上次发送的SYN报文丢失了,会再次重发SYN报文,此时,Server端又会分配资源,造成资源的浪费。但是我并不认为这个理由能站住脚,因为我觉得Server端在再次接收相同的Client端的SYN时,它完全可以根据报文的头部知道该SYN为上次同一Client端发送过来的,它可以不重新分配资源呀,它就会想,我这边对你的连接已经建立成功了呀,你为什么还发SYN来呢,那肯定是因为我刚刚发给你的SYN+ACK报文丢失了,那我重新给你发一次吧,由于它知道是同一个Client端发来的,它完全可以不重新分配资源呀。我看网上还有一种解释,如下:

具体可参考链接:http://blog.chinaunix.net/uid-20665047-id-3137792.html

void Sift(A[],int n,int k)
{
	int i = k;
	int j = 2*i;
	while(j
阅读(1487) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~