您的位置:首页 > 理论基础 > 计算机网络

uIP TCP Server 运行机制分析

2014-03-11 09:35 169 查看
uIP TCP Server 运行机制分析

        
        对于任何一个协议栈而言,首先要实现的就是TCP Server,下面看看uIP的运行机制:

        ①IP地址以及端口的绑定

        uIP在初始化时进行了本机地址IP地址的默认初始化,并将其存放在一个名为uip_hostaddr的结构体中,本机默认为192.168.1.11同样对子网掩码和网关也进行了默认设置。如果用户需要修改时,使用uip_sethostaddr()函数就可以使用新的IP地址对默认值进行覆盖,当然也要设置相应的网关与子网掩码。另外,使用uip_listen(HTONS(1000))进行端口的绑定,也就是说本机只侦听来自端口1000发来的请求。(数据发送是按哪个端口发送呢?)

        ②下面看一看数据流通信的过程

         使用上位机软件连接远程IP以及为192.168.1.11:1000,对其发起连接,实际上是进行三次握手操作,可以看到如下数据流:

         在程序的主循环中,轮询读取网卡中新的数据包

         uip_len= tapdev_read()

         如果收到的是一个IP包,那么要对数据格式进行判断,进入

         uip_input()同时传入一个flag==1,代表接收到一个新的数据包,首先剥离IP包头,指向其中的数据,接着对数据包个数进行统计UIP_STAT(++uip_stat.ip.recv);

        检查IP协议版本号,如果正确则计算数据长度:

        if((BUF->len[0]<< 8) + BUF->len[1] <= uip_len) {

        uip_len = (BUF->len[0] << 8) + BUF->len[1];计算数据长度

        检查数据包的目的IP是否为本机地址:

        if(!uip_ipaddr_cmp(BUF->destipaddr,uip_hostaddr)) {

                UIP_STAT(++uip_stat.ip.drop);

                goto drop;

        }

        如果是发往本机的数据包,那么就检查数据包校验和

         if(uip_ipchksum()!= 0xffff) ,如果正确的话就说明这是一个完整的IP包,那上层协议是什么呢?下面检查协议类型,如果是TCP数据包,就跳转到goto tcp_input,如果是UDP数据包,就跳转到goto udp_input去执行,如果是ping包发来的icmp请求就写入回复标志,交换IP,返回回应包。本次试验发送的是一个TCP连接请求,所以要对TCP数据包进行处理。

         判定了是一个TCP数据包,就要对数据包个数进行计数,有利于数据统计。下面再计算

TCP数据包校验和是否正确 if(uip_tcpchksum()!= 0xffff) 。

         下面的查看现有是否存在有效连接。众所周知,TCP server允许多个TCP client同时对其连接,使用for(uip_connr = &uip_conns[0]; uip_connr <= &uip_conns[UIP_CONNS- 1];

     ++uip_connr)查看,如果已经建立了有效连接,就到goto found;此时,通过抓包工具已经可以看出

我们的目标板已经发送了一个数据帧做了SYN的应答,下面可以看到这一过程。

         就是,如果没有发现有效的连接,现在只用接收TCP_SYN同步数据包,如果是一个TCP_SYN同步数据包,并且是已经注册的监听端口,就到found_listen处执行进行连接注册,把源端口、目的端口、源IP地址记录下来(肯定是发往目标板端口的),然后建立BUF->flags = TCP_SYN | TCP_ACK标志,tcp_send将回应包发出去。看到这里就不难明白goto found;之前那几行代码的用意了,就是寻找已经建立好的连接。

         那么我们接着往found下面看:

         既然是有效的连接,那么接下来要看发来的数据包有没有有效的数据,可以计算数据长度得知uip_len的多少,如果if(uip_len > 0) uip_flags |= UIP_NEWDATA;就说明接收到了新的数据,调用UIP_APPCALL()进行处理,之后通过UIP_APPCALL()调用处理之后的函数发出去。

        ③应用程序调用

       下面看一下UIP_APPCALL()是如何对数据进行解析和处理的。在这里我做了一个简单的测试,使用TCP&UDP调试工具想目标机发送一个指令,下位机进行解析处理以及返回。先看一个数据结构:struct uip_conn{},这个结构体代表了一个TCP的连接关系,记录当前数据包的状态。

        在这个结构体的最后定义应用程序定义的结构体tcp_demo_appstate,这里面可以定义一些状态作为TCP数据控制的补充,也可以实现状态机控制数据处理。TCP数据指针为uip_appdata,数据长度为uip_len,可以对其复制新的数据值以及新的数据长度,出去包头可以传输的最大数据段为1460个字节。

        uIP这个协议栈在uIP.c中实现了数据帧的校验,实现了连接的建立与查询以及用户程序的调用,考虑缜密,简单强大。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: