手把手教你捕获数据包【数据包的游戏系列之二】 by PiggyXP【小猪】

深入理解Windows完成端口:PiggyXP项目源码解析 I/O完成数据结构通常包含以下几个字段:// 完成键值// 实际传输的字节数// 指向OVERLAPPED结构的指针Key:与I/O请求关联的完成键值,这个值在请求提交时指定。:I/O操作实际传输的数据量。Overlapped:指向发起I/O请求时使用的OVERLAPPED结构体。 阅读详情

前   言

     经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,也写过很多的sniffer,所以就想写一系列的文章来详细深入的探讨关于数据包的知识。

我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带有详细注释的源码(为了照顾大多数朋友,我提供的都是MFC的源码)。

不过由于也是初学者,疏漏之处还望不吝指正。

本文凝聚着笔者心血,如要转载,请指明原作者及出处,谢谢!^_^

 

OK,. Let’s go !  Have fun!! q^_^p

 

第二篇   手把手教你捕获数据包

目录:

一.捕获数据包的实现原理

二.捕获数据包的编程实现:

1.   raw socket的实现方法

2.   Winpcap的实现方法

a.      枚举本机网卡的信息

b.      打开相应网卡并设置为混杂模式

c.       截获数据包并保存为文件

 

作者:

优快云  VC/MFC 网络编程版主 PiggyXP 

 

一.捕获数据包的实现原理:--------------------------------------------------------------------

在通常情况下,网络通信的套接字程序只能响应与自己硬件地址相匹配的或是以广播形式发出的数据帧,对于其他形式的数据帧比如已到达网络接口但却不是发给此地址的数据帧,网络接口在验证投递地址并非自身地址之后将不引起响应,也就是说应用程序无法收取与自己无关的的数据包。

所以我们要想实现截获流经网络设备的所有数据包,就要采取一点特别的手段了:

将网卡设置为混杂模式。

这样一来,该主机的网卡就可以捕获到所有流经其网卡的数据包和帧。

但是要注意一点,这种截获仅仅是数据包的一份拷贝,而不能对其进行截断,要想截断网络流量就要采用一些更底层的办法了,不在本文的讨论范围之内。

 

二. 捕获数据包的编程实现:

1.raw socket的实现方法--------------------------------------------------------------------

不同于我们常用的数据流套接字和数据报套接字,在创建了原始套接字后,需要用WSAIoctl()函数来设置一下,它的定义是这样的

int WSAIoctl(

  SOCKET s,

  DWORD dwIoControlCode,

  LPVOID lpvInBuffer,

  DWORD cbInBuffer,

  LPVOID lpvOutBuffer,

  DWORD cbOutBuffer,

  LPDWORD lpcbBytesReturned,

  LPWSAOVERLAPPED lpOverlapped,

  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine

);

虽然咋一看参数比较多,但是其实我们最关心的只是其中的第二项而已,我们需要做的就是把第二项设置为SIO_RCVALL,讲了这么多其实要做的就是这么一行代码,很简单吧?^_^

 当然我们还可以指定是否亲自处理IP头,但是这并不是必须的。

完整的代码类似与如下这样,加粗的代码是与平常不同的需要注意的地方:

( 为了让代码一目了然,我把错误处理去掉了,下同)

 

#include “WinSock2.h”

#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)

 

SOCKET SnifferSocket

  WSADATA wsaData;

  iFlag=WSAStartup(MAKEWORD(2,2),&wsaData);           //开启winsock.dll

                                 

SnifferSocket=WSASocket(AF_INET,             //创建raw  socket

SOCK_RAW,IPPROTO_IP,NULL,0,WSA_FLAG_OVERLAPPED);

 

  char FAR name[128];                                //获取本机IP地址

gethostname(name, sizeof(name));

  struct hostent FAR * pHostent;

  pHostent = gethostbyname(name);

 

  SOCKADDR_IN sa;                           //填充SOCKADDR_IN结构的内容

  sa.sin_family = AF_INET;

  sa.sin_port = htons(6000);           // 端口号可以随便改,当然与当然系统不能冲突

  memcpy(&(sa.sin_addr),pHostent->h_addr,pHostent->h_length);

 

bind(SnifferSocket,(LPSOCKADDR)&sa,sizeof(sa));            //绑定

 

  // 置ioctl来接收所有网络数据,关键步骤

  DWORD dwBufferLen[10] ;

  DWORD dwBufferInLen = 1 ;

  DWORD dwBytesReturned = 0 ;

  WSAIoctl(SnifferSocket, IO_RCVALL,&dwBufferInLen, izeof(dwBufferInLen),

        &dwBufferLen, sizeof(dwBufferLen),&dwBytesReturned , NULL , NULL );

 

至此,实际就可以开始对网络数据包进行嗅探了,而对于数据包的接收还是和普通的socket一样,通过recv()函数来完成,因为这里涉及到不同的socket模型,接收方法差别很大,所以在此就不提供接收的代码了。

 

2.winpcap的实现方法:-----------------------------------------------------------------------

winpcap驱动包,是我们玩转数据包不可或缺的好东东,winpcap的主要功能在于独立于主机协议(如TCP-IP)而发送和接收原始数据报,主要为我们提供了四大功能:

功能:
    1>
捕获原始数据报,包括在共享网络上各主机发送/接收的以及相互之间交换的数据报;
    2>
在数据报发往应用程序之前,按照自定义的规则将某些特殊的数据报过滤掉;
    3>
在网络上发送原始的数据报;
    4>
收集网络通信过程中的统计信息

如果环境允许的话(比如你做的不是木马程序),我还是推荐大家用winpcap来截获数据包,因为它的功能更强大,工作效率更高,唯一的缺点就是在运行用winpcap开发的程序以前,都要在主机上先安装winpcap的driver。

而且一会我们就会发现它比raw socket功能强大的多,而且工作得更为底层,最明显的理由就是raw socket捕获的数据包是没有以太头的,此乃后话。

至于怎么来安装使用,请参考本系列的系列一《手把手教你玩转ARP包中的》,里面有详细的加载winpcap驱动的方法^_^

废话不多说了,让我们转入正题, 具体用winpcap来截获数据包需要做如下的一些工作:

A . 枚举本机网卡的信息(主要是获得网卡的名称)

   其中要用到pcap_findalldevs函数,它是这样定义的

   /*************************************************

int pcap_findalldevs  (  pcap_if_t **    alldevsp, 

                             char *    errbuf

                          ) 

     功能:

             枚举系统所有网络设备的信息

     参数:  alldevsp:  是一个pcap_if_t结构体的指针,如果函数pcap_findalldevs函数执行成功,将获得一个可用网卡的列表,而里面存储的就是第一个元素的指针。

             Errbuf:    存储错误信息的字符串

     返回值: int :   如果返回0 则执行成功,错误返回 -1。

  *************************************************/

   我们利用这个函数来获得网卡名字的完整代码如下:

 

       pcap_if_t* alldevs;

       pcap_if_t* d;

       char errbuf[PCAP_ERRBUF_SIZE];

       pcap_findalldevs(&alldevs,errbuf);       // 获得网络设备指针

       for(d=alldevs;d;d=d->next)               // 枚举网卡然后添加到ComboBox中

       {

d->name;                            // d->name就是我们需要的网卡名字字符串,按照你// 自己的需要保存到你的相应变量中去

       }

pcap_freealldevs(alldevs);               // 释放alldev资源

 

请期待下文。。。。。^_^

B. 打开相应网卡并设置为混杂模式:

   在此之前肯定要有一段让用户选择网卡、并获得用户选择的网卡的名字的代码,既然上面已经可以获得所有网卡的名字了,这段代码就暂且略过了。

   我们主要是要用到 pcap_open_live 函数,不过这个函数winpcap的开发小组已经建议用pcap_open 函数来代替,不过因为我的代码里面用的就是pcap_open_live,所以也不便于修改了,不过pcap_open_live使用起来也是没有任何问题的,下面是pcap_open_live的函数声明:

 /*************************************************

pcap_t* pcap_open_live  (  char *    device, 

                             int    snaplen, 

  int    promisc, 

  int    to_ms, 

  char *    ebuf

 )  

     功能:

           根据网卡名字打开网卡,并设置为混杂模式,然后返回其句柄

     参数:

           Device  : 就是前前面我们获得的网卡的名字;

           Snaplen :  我们从每个数据包里取得数据的长度,比如设置为100,则每次我们只是获得每个数据包 100 个长度的数据,没有什么特殊需求的话就把它设置为65535最大值就可以了;

           Promisc:这个参数就是设置是否把网卡设置为“混杂模式”,设置为 1 即可;

           to_ms :   超时时间,毫秒,一般设置为 1000即可。

     返回值:

           pcap_t :  类似于一个网卡“句柄”之类的,不过当然不是,这个参数是后面截获数据要用到的。

******************************************************************************/

虽然看起来比较复杂,不过用起来还是非常简单的,其实 1 行就OK了:

    pcap_t* adhandle;

       char errbuf[PCAP_ERRBUF_SIZE];

// 打开网卡,并且设置为混杂模式

// pCardName是前面传来的网卡名字参数

adhandle = pcap_open_live(pCardName,65535,1,1000,errbuf);

 

C. 截获数据包并保存为文件:------------------------------------------------------

     当然,不把数据包保存为文件也可以,不过如果不保存的话,只能在截获到数据包的那一瞬间进行分析,转眼就没了^_^

所以,为了便于日后分析,所以高手以及我个人经常是把数据包保存下来的慢慢分析的。

但是注意网络流量,在流量非常大的时候注意硬盘空间呵呵,常常几秒中就有好几兆是很正常的事情。

下面首先来详细讲解一下,这个步骤中需要用到的winpcap函数:

/**************************************************************

pcap_dumper_t* pcap_dump_open  (  pcap_t *    p, 

                                      const char *    fname

 )

功能:

      建立或者打开存储数据包内容的文件,并返回其句柄

参数:

       pcap_t *    p     :前面打开的网卡句柄;

      const char * fname :要保存的文件名字   

返回值:

       pcap_dumper_t* : 保存文件的描述句柄,具体细节我们不用关心

***************************************************************/

/***************************************************************

int pcap_next_ex          (  pcap_t *    p, 

                              struct pcap_pkthdr **    pkt_header, 

  u_char **    pkt_data

 )  

功能:

      从网卡或者数据包文件中读取数据内容

参数:

      pcap_t *    p:    网卡句柄

      struct pcap_pkthdr ** pkt_header: 并非是数据包的指针,只是与数据包捕获驱动有关的一个Header

      u_char ** pkt_data:指向数据包内容的指针 ,包括了协议头  

返回值:

          1 : 如果成功读取数据包

          0 :pcap_open_live()设定的超时时间之内没有读取到内容

          -1: 出现错误

          -2: 读文件时读到了末尾

***************************************************************/

/***************************************************************

void pcap_dump  (  u_char *    user, 

                       const struct pcap_pkthdr *    h, 

  const u_char *    sp

 )   

功能:

      将数据包内容依次写入pcap_dump_open()指定的文件中

参数:

      u_char * user   :  网卡句柄

      const struct pcap_pkthdr * h: 并非是数据包的指针,只是与数据包捕获驱动有关的一个Header

      const u_char * sp: 数据包内容指针    

返回值:

          Void

****************************************************************/

 下面给出一段完整的捕获数据包的代码,是在线程中写的,为了程序清晰,我去掉了错误处理代码以及线程退出的代码,完整代码可下载文后的示例源码,老规矩,重要的步骤用粗体字标出。

我们实际在捕获数据包的时候也最好是把代码放到另外的线程中。

/*********************************************************

*   进程:

*                   这个是程序的核心部分,完成数据包的截获

*     参数:

*                   pParam: 用户选择的用来捕获数据的网卡的名字

*********************************************************/

UINT CaptureThread(LPVOID pParam)

{

       const char* pCardName=(char*)pParam;          // 转换参数,获得网卡名字                       

 

       pcap_t* adhandle;

       char errbuf[PCAP_ERRBUF_SIZE];             

       // 打开网卡,并且设置为混杂模式

 adhandle=pcap_open_live(pCardName,65535,1,1000,errbuf);      {

 

       pcap_dumper_t* dumpfile;

// 建立存储截获数据包的文件

       dumpfile=pcap_dump_open(adhandle, "Packet.dat");   

 

       int re;

       pcap_pkthdr* header;      // Header

       u_char* pkt_data;         // 数据包内容指针

// 从网卡或者文件中不停读取数据包信息

       while((re=pcap_next_ex(adhandle,&header,(const u_char**)&pkt_data))>=0)

      {

          // 将捕获的数据包存入文件

              pcap_dump((unsigned char*)dumpfile,header,pkt_data);     

       }

       return 0;

}  

将个线程加入到程序里面启动以后。。。等等,如何来启动这个线程就不用我说了吧,类似这样的代码就可以

::AfxBeginThread(CaptureThread,chNIC);     // chNIC是网卡的名字,char* 类型

启动线程一段时间以后(几秒中就有效果了),可以看到数据包已经被成功的截获下来,并存储到程序目录下的Packet.dat文件中。

=====================================================

至此,数据包的截获方法就讲完了,大家看了这篇文章,其实你就一定也明白了,无论是raw socket的方法还是winpcap的方法,其实都很简单的,真的没有什么东西,只是会让不明白原理的人看起来很神秘而已,isn’t it?

呵呵,不过也不要高兴的太早,这个保存下来的数据包文件,你可以试着用UltraEdit打开这个文件看看,是不是大部分都是乱码?基本上没有什么可读性,这是因为:

此时捕获到的数据包并不仅仅是单纯的数据信息,而是包含有 IP头、 TCP头等信息头的最原始的数据信息,这些信息保留了它在网络传输时的原貌。通过对这些在低层传输的原始信息的分析可以得到有关网络的一些信息。由于这些数据经过了网络层和传输层的打包,因此需要根据其附加的帧头对数据包进行分析。

呵呵,所以我们要走的路还很长,这只是刚刚入门而已^_^

请期待本系列的下一部拙作

《手把手教你分析数据包》

本文的源码也将在下一文中一起发布

 

                                                                                                                 --------  Made In DLUT | DIP

                                                                                                                   --------  Finished at 2004-06-23

piggyxp小猪IOCP项目源码 这份代码是我博客里的文章《完成端口详解 - 手把手教你玩转网络编程系列之三》的配套代码 里面的代码包括VC++2008/VC++2010编写的完成端口服务器端的代码,还包括一个对服务器端进行压力测试的客户端,都是经过我精心调试过,并且带有非常详尽的代码注释的。当然,作为教学代码,为了能够使得代码结构清晰明了,我还是对代码有所简化,如果想要用于产品开发,最好还是需要自己再完善一下 详情请参见我的博客 http://blog.youkuaiyun.com/piggyxp 立即下载

相关推荐

Windows IOCP实例 - 改编自PiggyXP

使用VS2015 unicode重新编译,新增了服务端回传数据的功能,压测客户端增加了实际压测的功能,并统计显示QPS

网络编程模型之完成例程

PiggyXP—系列1:https://blog.youkuaiyun.com/PiggyXP/article/details/3910726 PiggyXP—系列2:https://blog.youkuaiyun.com/PiggyXP/article/details/3911121 PiggyXP—系列3:https://blog.youkuaiyun.com/PiggyXP/article/details/6922277 ...

Steven_programe_life的专栏 243

IOCPExample_By_PiggyXP 完成端口示例代码

完成端口示例代码:IOCPExample_By_PiggyXP.rar

完成端口(CompletionPort)详解 - 手把手教你玩转网络编程系列之三

手把手叫你玩转网络编程系列之三    完成端口(Completion Port)详解                                                              ----- By PiggyXP(小猪) 前 言         本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所以这篇文档总是在酝酿

小猪的网络编程 22万+

PiggyXP 完成端口的源码

作者原来的项目代码已经不能下载了,这里补上, 作者文章地址:http://blog.youkuaiyun.com/piggyxp/article/details/6922277 包含以下文件 IOCPExample_By_PiggyXP.rar PiggyStressTestClient.rar

IOCP演示代码 SDK版(改编自小猪IOCP教程源码)

小猪的IOCP教程和代码是目前我见过的最好的资源. 速度最快,架构最清晰, 建议到他空间去看一下:http://blog.youkuaiyun.com/piggyxp/article/details/6922277#quote 原作中使用MFC做的界面, 我这儿封装了一个SDK版的, 供不喜欢MFC的兄弟参考.

手把手教你玩转ARP包【数据包的游戏系列之一】 by PiggyXP【小猪】

前   言          首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料以及帮助^_^经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,,我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带

XmagicX的专栏 4686

VC网络编程模型示例 - 重叠IO模型

VC网络编程模型示例之 - 重叠IO模型 配套讲解请参考我的blog http://blog.youkuaiyun.com/PiggyXP

手把手教你玩转SOCKET模型之重叠I/O篇 by PiggyXP【小猪】

把手教你玩转SOCKET模型之重叠I/O篇  “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                                

XmagicX的专栏 2533

博客文章《完成端口详解》配套代码(压力测试客户端)

应广大朋友要求,这份代码是我博客里的文章《完成端口详解 - 手把手教你玩转网络编程系列之三》的配套代码的客户端部分

【Q1/论文复现】:利用 CHARLS 数据库考察抗高血压药物依从性和认知衰退

摘要: 北京大学团队基于CHARLS数据(2011-2018)的纵向研究发现,抗高血压药物高依从性能显著延缓中国45岁及以上社区中老年人的认知衰退。研究表明,坚持服药者7年内全局认知衰退速度降低0.014SD/年,记忆功能衰退减缓0.023SD/年,效果接近正常血压人群水平。研究还提示社会经济地位(SES)可能通过影响用药依从性间接调控认知衰老进程。该成果为高血压管理对认知保护提供了人群级证据,发表于《BMC Medicine》(DOI:10.1186/s12916-025-03949-8)。

dingdianbangni的博客 809

手把手教你玩转ARP包(一)【数据包的游戏系列之一】

前   言          首先要感谢网络安全资深专家卢湖川博士以及VC网络版的limin朋友提供的资料以及帮助^_^经常看到论坛有人问起关于数据包的截获、分析等问题,幸好本人也对此略有所知,所以就想写一系列的文章来详细深入的探讨关于数据包的知识,,我希望通过这一系列的文章,能使得关于数据包的知识得以普及,所以这系列的每一篇文章我都会有由浅入深的解释、详细的分析、以及编码步骤,另外附上带

小猪的网络编程 2万+

SOC Boot学习(二)——JTAG Debug介绍

JTAG(Joint Test Action Group ,联合测试行动小组 ) 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试。JTAG 技术是一种嵌入式调试技术,它在芯片内部封装了专门的测试电路 TAP ( Test Access Port ,测试访问口),通过专用的 JTAG 测试工具对内部节点进行测试。如今大多数比较复杂的器件都支持 JTAG 协议,如 ARM 、 DSP 、 FPGA 器件等。

yttt的博客 1606

兄弟,有没有PiggyXP【小猪】老大的ARP工程文件,发一个给我,谢谢了。邮箱:798063697@qq.com

<br />兄弟,有没有PiggyXP【小猪】老大的ARP工程文件,发一个给我,谢谢了。邮箱:798063697@qq.com

wanyihui1989的专栏 1149

基于YOLOv5的隧道衬砌缺陷智能检测系统

计算机视觉在工程检测领域正发挥越来越重要的作用,特别是目标检测技术通过深度学习算法实现了对复杂场景的智能分析。YOLOv5作为当前主流的目标检测框架,通过改进网络结构和训练策略,可以显著提升检测精度和效率。在隧道工程领域,结合通道注意力机制和多尺度特征融合技术,能够有效解决衬砌缺陷识别中的小目标检测难题。这种AI检测系统相比传统人工判读地质雷达图像,不仅将效率提升20倍,还能将识别准确率提高到92.3%,特别适用于3cm以上结构缺陷的自动化检测。系统通过深度可分离卷积等优化,实现了模型轻量化,便于在边缘计算

weixin_29064103的博客 326

2019年数学建模美赛经验总结

北京时间2019年1月29号上午9时,数模美赛结束。美赛结束已经10多天了,我在这次竞赛中负责建模和编程,趁现在记忆还比较清晰,写下这篇博客记录第一次参加数学建模美赛的经历。 补更:2019年4月20日公布成绩,笔者最终获得了美赛一等奖 目录 1、基本情况 2、选题 3、分工合作 4、论文写作 5、建模 6、编程 7、入门资源 ...

Smallactive 7万+

手把手教你玩转SOCKET模型之重叠I/O篇(上)

手把手教你玩转SOCKET模型之重叠I/O篇 “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”                                                              

小猪的网络编程 5万+

工程师必看:如何用功率谱密度搞定随机振动测试(附Grms计算实例)

本文为工程师详解如何通过功率谱密度(PSD)曲线计算Grms(总均方根加速度),从而量化随机振动测试的强度。文章拆解了平直谱、斜谱的计算公式,提供了完整的Grms计算实例,并指出了单位换算、对数坐标等常见工程陷阱,帮助工程师精准完成测试准备与设备推力评估。

3c4x5z6v7b的博客 626

完成端口(Completion Port)详解----- By PiggyXP(小猪)

本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所以这篇文档总是在酝酿之中……酝酿了两年之后,终于决定开始动笔了,但愿还不算晚…..         这篇文档我非常详细并且图文并茂的介绍了关于网络编程模型中完成端口的方方面面的信息,从API的用法到使用的步骤,从完成端口的实现机理到实际使用的注意事项,都有所涉及,并且为了让朋友们更直观的体会完成端口的用法

liujiayu2的专栏 2714

基于Python的雪球网投资组合数据爬取与分析实战:从入门到精通

在当今数字化投资时代,数据已成为投资者最重要的资产之一。雪球网作为中国领先的投资社交平台,汇聚了大量优质的投资组合数据,这些数据对于量化投资研究和个人投资决策具有重要价值。本文将详细介绍如何使用Python最新技术栈构建一个高效、稳定的雪球网投资组合爬虫,并深入分析获取的数据。投资组合持仓明细及变动历史投资收益率曲线与风险指标投资者操作策略与调仓频率热门行业与个股关注度。

2201_76125261的博客 920

RK356x U-Boot研究所(命令篇)3.7 pci与nvme命令的用法

RK356x U-Boot研究所(命令篇)3.7 pci与nvme命令的用法

Systemcall名屋 2084

完成端口(Completion Port)详解 转载来自博客园----- By PiggyXP(小猪)

完成端口(Completion Port)详解                                                              ----- By PiggyXP(小猪) 前 言         本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了,不知该如何提笔,所以这篇文档总是在酝酿之中……酝酿了两年之后

Xietong Blog 607

cesium 气象云(体积云)

本文介绍了基于Cesium的气象云渲染技术方案,其核心是通过GPU加速的光线投射算法实现气象云的三维可视化。方案采用分层架构设计:GPU计算层由顶点着色器和片段着色器组成,负责光线投射计算、3D纹理采样和颜色映射;CPU控制层处理数据预处理、纹理创建和参数配置。关键技术包括:顶点着色器计算相机位置和光线方向,片段着色器实现光线步进采样、颜色映射和半透明混合。该方案高效解决了气象数据与地理场景的融合问题,支持云图、温度场等复杂三维气象数据的实时渲染,具有高真实感和良好性能。

God's asylum的博客 1204

【小猪原创】手把手教你玩转SOCKET模型之 重叠I/O 篇

建议大家还是到我的blog上看彩版的吧,清晰醒目,我帖在这里只是为了引起大家注意..-_-b     在这里看这么多字简直是折磨自己的双眼啊......         “身为一个初学者,时常能体味到初学者入门的艰辛,所以总是想抽空作点什么来尽我所能的帮助那些需要帮助的人。我也希望大家能把自己的所学和他人一起分享,不要去鄙视别人索取时的贪婪,因为最应该被鄙视的是不肯付出时的吝啬。”        

wang_54439463的专栏 1154

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

上一篇: 创建SvcHost.exe调用的服务原理与实践 by PiggyXP
下一篇: 手把手教你玩转SOCKET模型之重叠I/O篇 by PiggyXP【小猪】
XmagicX
博客等级 码龄24年 13粉丝 78原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值