新闻中心

EEPW首页>嵌入式系统>设计应用> 单片机图像采集与网络传输

单片机图像采集与网络传输

作者: 时间:2012-03-20 来源:网络 收藏

3.4数据的封装

32.gif

DB200完1帧后,通过数据总线传送给89C52;89C52则将数据按TCP/IP协议封装成以太网帧(图3),然后通过数据总线送给RTL8019AS;RTL8019AS则将以太网帧经RJ45接口送到10M以太网上。

从图3可以看到,每个以太网帧的最大长度为1518字节,最小为64字节。其数据部分最大为1500字节,最小为46字节。每个UDP数据传输前,必须加上 8字节的UDP头来构成UDP数据报;再加上20字节的IP头来构成IP数据报;最后加上14字节的帧头来构成以太网帧。这就是所谓的数据包封装。为了避免分段操作的麻烦,UDP数据报的最大长度应为1500 - 28=1472字节。在实际应用中,我们采用每行图像数据(385字节)封装一个包的方式传输数据。
void Data_send( UINT src_port, UINT datalen) // (例程5--UDP数据报封装):
{ UDP_HEADER xdata * udp;
udp = (UDP_HEADER xdata *)(outbuf + 34); // 34=14(以太网帧头长)+ 20(IP报头长) udp->dest_port = 2001; // 目的端口号
udp->source_port = 20011; // 源端口号
udp->length = 8 + datalen; // UDP包总长= UDP头长度+数据长度
udp->checksum = 0; // 不校验UDP数据报
ip_pack(outbuf, dest_ipaddr, udp->length); // 封装IP包
}
void ip_pack(UCHAR xdata * outbuf, ULONG dest_ipaddr, UINT datalen)//(例程6-封装IP包)
{ IP_HEADER xdata * ip; static UINT ip_ident; // datalen为UDP数据报总长度
ip = (IP_HEADER xdata *)(outbuf + 14); // 14字节为以太网帧头长度。
ip->ver_len = 0x45; ip->type_of_service = 0; // 版本号和服务类型。
ip->total_length = 20 + datalen; // 数据报总长=IP头长度+数据长度
ip->identifier = ip_ident++; // IP数据报序列号。
ip->fragment_info = 0; // IP数据报不分段。
ip->time_to_live = 32; // 生存时间。
ip->protocol_id = UDP_TYPE; // 协议类型为UDP=17。
ip->header_cksum = 0; // 校验和清0。
ip->dest_ipaddr = 0xEA050607L; // 0xEA050607L=234.5.6.7 为目标组播地址
ip->source_ipaddr = 0xD224446FL; // 0xD224446FL=210.36.68.111为本地IP地址
ip->header_cksum = ~cksum(outbuf + 14, 20); // 计算20字节的IP数据报头校验和
eth_send(outbuf, 34 + datalen); // 封装以太网帧并发送。
}

在上述例程5和例程6中,UDP的校验和是可选的,IP头的校验和是必需的。例程5将UDP检验和置为0,例程6则用cksum( )函数来计算IP头校验和。本地IP地址可取任意有效值。

3.5 以太网帧的封装和发送

从图3可知,以太网帧封装就是要将目的MAC地址、源MAC地址和所要传输的数据类型放到待发送的IP数据报前(成为以太网帧头)。因为我们要进行的是组播发送,所以目的MAC地址也必须是组播的MAC地址;而本地的源MAC地址我们就用01:02:03:04:05:06。



评论


相关推荐

技术专区

关闭