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

时间:2022-05-08
本文章向大家介绍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:%dn", 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 ("计数+1n");
32                 if (nNum > WARN_NUM) {//计数超过了阈值参数
33                     g_bWarning = true;
34                     pcap_breakloop(g_OpenDev);
35                 }
36         }
37     }
38     
39     
40 }