C/C++网络编程时注意的问题小结

1.网络编程在自己定义结构体实现协议的时候,一定要注意字节对齐这个问题。否则sizeof和强制转换指针的时候都会出现很难发现的bug。

什么是字节对齐自行百度。

 1 #pragma pack (1)//字节对齐的控制!非常注意!
 2 //定义一个以太网头部
 3 typedef struct ehhdr
 4 
 5 {
 6 
 7     UCHAR    eh_dst[6];        /* destination ethernet addrress */
 8 
 9     UCHAR    eh_src[6];        /* source ethernet addresss */
10 
11     USHORT   eh_type;          /* ethernet pachet type    */
12 
13 }ETHERHEAD;
14 
15 //28字节的ARP请求/应答
16 
17 typedef struct arphdr
18 
19 {
20 
21     USHORT    arp_hrd;            /* format of hardware address */
22 
23     USHORT    arp_pro;            /* format of protocol address */
24 
25     UCHAR     arp_hln;            /* length of hardware address */
26 
27     UCHAR     arp_pln;            /* length of protocol address */
28 
29     USHORT    arp_op;             /* ARP/RARP operation */
30 
31     UCHAR     arp_sha[6];         /* sender hardware address */
32 
33     ULONG     arp_spa;            /* sender protocol address */
34 
35     UCHAR     arp_tha[6];         /* target hardware address */
36 
37     ULONG     arp_tpa;            /* target protocol address */
38 
39 }ARPHEAD;
40 
41 #pragma pack ()//字节对齐的控制

2. 注意网络字节序和本机字节序的转换。使用ntohs()等函数。下面是一个winpcap回调函数的例子,用来检测本机是否在进行ARP扫描,对代码有任何建议欢迎指出交流。

 1 void packet_handler_ARP(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
 2 {
 3     struct tm *ltime;
 4     ltime = new struct tm;
 5     char timestr[16];
 6     time_t local_tv_sec;
 7     time_t tTimer = time(0);
 8     static unsigned short nNum;
 9 
10     if ( tTimer - g_tStartTimer > SNIFF_TIME)//计时嗅探时间
11          pcap_breakloop(g_OpenDev);
12 
13     /* 将时间戳转换成可识别的格式 */
14     local_tv_sec = header->ts.tv_sec;
15     localtime_s(ltime, &local_tv_sec);
16     strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);
17     
18     printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
19 
20     //嗅探自己是否发出了ARP
21     ETHERHEAD *pEtherHead = NULL;
22     pEtherHead = (ETHERHEAD*)pkt_data;
23     if ( strncmp((const char*)(pEtherHead->eh_src), (const char*)(g_aMac), 6) == 0) {//检测源地址是否是本机
24         ARPHEAD *pARPHead = NULL;
25         //printf ("是本机发出的ARP数据");
26         pARPHead = (ARPHEAD*)(pkt_data + sizeof(ETHERHEAD));
27         if (ntohs (pARPHead->arp_pro) == 0x0800 &&//IP
28             ntohs(pARPHead->arp_op) == 0x0001 &&//ARP Request
29             (ntohl(pARPHead->arp_tpa) & 0xffff0000)== 0xc0a80000 ) {//是ARP请求内网IP
30                 nNum ++;
31                 //printf ("计数+1\n");
32                 if (nNum > WARN_NUM) {//计数超过了阈值参数
33                     g_bWarning = true;
34                     pcap_breakloop(g_OpenDev);
35                 }
36         }
37     }
38     
39     
40 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏落影的专栏

使用AudioToolbox播放AAC

前言 使用VideoToolbox硬编码H.264 使用VideoToolbox硬解码H.264 使用AudioToolbox编码AAC 在上一篇中,介绍...

4224
来自专栏Java架构师学习

Zookeeper-watcher机制源码分析(二)

其大致流程如下   ① 通过传入的path(节点路径)从watchTable获取相应的watcher集合,进入②

1551
来自专栏三好码农的三亩自留地

Android Handler实现原理探索

    Android Handler我们都很熟,也经常也用它,一般可以用Handler发送一个消息Message,或者Post一个Runnable对象,而且都...

1742
来自专栏大内老A

WCF的Binding模型之四:信道工厂(Channel Factory)

由于信道管理器在客户端和服务端所起的不同作用,分为信道监听器和信道工厂。和服务端的信道监听其相比,处于客户端的信道工厂显得简单。从名称就可以看得出来,信道工厂的...

1828
来自专栏编码小白

tomcat请求处理分析(一) 启动container实例

1.1.1  启动container实例 其主要是进行了生命周期中一系列的操作之后调用StandardEngine中的 startInternal方法,不难看出...

3846
来自专栏Golang语言社区

50. RESTful API的简单实现 | 厚土Go学习笔记

RESTfull API是现在很流行的 API 设计风格。众所周知的 HTTP 1.1规范正是基于 REST 架构风格的指导原理来设计的。需要注意的是,REST...

2884
来自专栏积累沉淀

Java设计模式(十九)----备忘录模式

备忘录模式 一、 概念 二、 结构 三、 分类 1.”白箱”备忘录模式的实现 2.“黑箱”备忘录模式的实现 3.“多重”检查点 4....

1999
来自专栏海说

12、借助Jacob实现Java打印报表(Excel、Word)

12、使用Jacob来处理文档   Word或Excel程序是以一种COM组件形式存在的。如果能够在Java中调用相应组件,便能使用它的方法来获取文档中的文本信...

5580
来自专栏小灰灰

Batik渲染png图片异常的bug修复全程记录

batik是apache的一个开源项目,可以实现svg的渲染,后端借助它可以比较简单的实现图片渲染,当然和java一贯处理图片不太方便一样,使用起来也有不少坑

2567
来自专栏小灰灰

Batik渲染png图片异常的bug修复

Batik渲染png图片异常的bug修复 batik是apache的一个开源项目,可以实现svg的渲染,后端借助它可以比较简单的实现图片渲染,当然和java一贯...

2029

扫码关注云+社区

领取腾讯云代金券