1.3 数据的接收 之 数据接收全程实例分析

本文解析了一个完整的UDP协议数据接收客户端程序。介绍了程序如何初始化Wattcp、设置通信协议及基本信息,以及如何进行数据接收和处理的过程。

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

#include <stdio.h> 
#include <mem.h> 
#include <wattcp.h> 
int main(int argc, char *argv[]) 
{ 
    unsigned long host = -1;//默认是广播地址,即可以接收一切主机发送来的消息 
    udp_Socket s; 
    char myaddr[20], hisaddr[20]; 
    char strData[512];// 接收到的数据 
    char strBuffer[2048];// 缓冲 
    int blGotdata = 0, iPort = 5150, iMyPort = 5150;

     sock_init(); 
     if ( !udp_open(&s, iMyPort, host, iPort, NULL)) 
     { 
          puts("Could not open broadcast socket"); 
          return 3; 
     } 
     if ( sock_recv_init(&s, strBuffer, sizeof(strBuffer))) 
     { 
          puts("Could not enable large buffers"); 
          return 3; 
     } 
     while(1) 
     { 
        tcp_tick(&s); 
        memset(strData, 0, strlen(strData)); 
        blGotdata = sock_recv_from(&s, (long *)&host, (word *)&iPort, strData, sizeof(strData), NULL); 
        if(blGotdata > 0) 
        { 
            printf("[%s:%ld] send me: %s\n", inet_ntoa((char *)hisaddr, (unsigned long)intel(host)), (unsigned long)intel16(iPort), strData); 
        } 
     }
     return 0;
}

​ 上面是一个完完整整的接受UDP协议数据的客户端程序.
​ 首先,需要对Wattcp进行初始化。这个过程是通过调用sock_init();其调用关系是:
sock_init() ==> sock_init_noexit() ==> tcp_init_noexit() ==> _eth_init() ==> _pkt_eth_init() ==> pkt_init()
​ 对于pkt_init()函数我在最初《初来乍到》中就有过介绍,它的主要作用就是初始化网卡,调整网卡的工作模式,并告诉网卡驱动我也需要接受/发送网络数据包。
从这个初始化过程我们就可以看到处理TCP/IP协议所使用的层数了,三层。最上面是socket,主要是封装,便于使用。中间是协议,包括TCP、IP等协议的处理。最下边是硬件,也就是驱动程序、硬件设备等等。其中sock_init() ==> sock_init_noexit()属于最上层,tcp_init_noexit()是中间层,`_eth_init() ==> _pkt_eth_init() ==> pkt_init()是最下层。
​ 在linux下,最下层可能不是网络,而是进程间通信。于是,成为一种进程间通信的方式。读linux内核源码时,着实被其处理方式折服了一番。

​ 接下来就是告诉Wattcp我们使用什么协议进行通信,以及用于通信的一些基本信息。udp_open()就是用来完成这个工作的。这个函数实际上仅仅是对传入的套接字进行了初始化。当然,也使用Arp协议来获取了服务器端的MAC地址。但是,Arp协议比较简单,就留给感兴趣的自己分析吧。只要顺着_arp_resolve()看下去就可以了。
sock_recv_init()也是进行初始化工作,它是给Wattcp提供一个数据缓冲区,让Wattcp把接受到数据先存放到这儿来。

​ 最后就是数据的取出了,我们通过调用sock_recv_from()来完成。实际上,sock_recv_from()仅仅是从前面调用sock_recv_init()设置的缓冲区种拷贝出来。如果长时间不往外拷贝并且缓冲使用完了,后面的包就会覆盖掉前面的包。于是,出现丢包现象。之所以DOS下容易出现丢包现象就是因为缓冲区太小,数据来不及处理就丢掉了。

​ 您看,实际上数据的接受是非常简单的。同样,数据的发送也是一样的简单。记住“源码之下了无秘密”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值