C语言判断数据包包头函数的简单介绍
在C语言中,怎么理解包头和包体的概念! [
似乎C语言的指针是个人们永远都讨论不完的话题,无论是初学者还是老手。那么下面简单说说我对指针的一些浅薄的理解。
成都创新互联公司是一家集网站建设,伊美企业网站建设,伊美品牌网站建设,网站定制,伊美网站建设报价,网络营销,网络优化,伊美网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。
需要首先明确的是C语言中的指针是一种数据类型,单从这点上来看,指针和int,float什么的没什么大区别,但是指针这种数据类型所存储的东西可就大有讲究了。
我们都清楚,程序是要在内存中执行的,在内存中执行的话就必须得有个确认位置的方法,这个方法就是内存的地址。也就是说,一个运行中的程序中的所有的“部件”(指令,数据什么的),都在内存中放着呢,也就是他们都有地址。那么指针呢,就是专门用来存放这些内存地址的一种变量。因为它存放的值是地址,这就导致了指针变量和其他类型变量有很大的不同。
指针具有两大特点,一是指针变量本身的值。这个值刚才说了,就是别的数据的地址(变量)或者指令的地址(函数),这个地址可以理解为一种间接访问他人的“线索”,也就是说,通过指针变量中存放的地址,可以访问某些数据或者实现指令的跳转。既然是变量,那肯定有自己存储空间的大小了。那么指针变量的大小是多少呢?这个非常简单:指针是用来存放地址的,那么指针变量的长度当然就是其所在机器地址总线的长度了!比如在32位的x86上,指针一般来说就是32位的,也就是4个字节大小。二就是指针变量的类型。我们都知道再声明指针变量的时候都得指名类型,比如char */int *等,那么这里的char/int之类的又有什么含义呢?我认为可以把这些类型理解成一种“尺度”,或者说是一种“权限”。如刚才所说,指针的值指明了可以访问的位置,那么指针的类型则限制了指针从该位置所能访问的长度。比如,
int *p 说明了p这个指针变量在使用诸如*p等方式访问p中存放的地址中的数据的时候,系统会提取sizeof(int)长度的数据出来,这个数据当然就是一个int型的值了,或者在进行诸如p++这样的操作时,系统会加上sizeof(int)的长度。总而言之,指针其实就是一个地址加一个长度,地址限定了指针起始的位置,而长度则规定了系统按什么方式来解析内存的数据。
有了以上的说明,下面将要唠叨的有关于指针强制类型转换的概念就很好理解了
指针的强制类型转换很好理解,转换的就是指针的类型,也就是系统使用指针的方式。比如从int*转换到char*,那么指针中的地址并没有变化,只是类型变了,比如在执行p++的时候,原来是增加4个字节(32位int),而转换之后便成了增加1个字节(char的长度)。再复杂一点,常规类型向结构体的强制类型转换也是这样的道理。在Linux的网络编程中常常用到将某种指针强制转换成某种协议包头的struct,然后提取该包头的数据(由于最近小研究了一下pcap,对这个比较熟悉^_^)或者各种结构体的指针之间进行类型转换。这些转换其实都是在改变系统对从某一地址开始的一堆数据的不同的解释方法。比如在pcap中,抓取的以太网数据包(当然在内存中存在)的地址被存放到了一个u_char类型的指针中,这个指针其实就是一个存有整个数据包所有信息的一块内存空间的开始地址!但是如果使用char类型的指针来一个字节一个字节的访问该内存段当然无法取得正确的数据,所以要把u_char转换成相应的网络协议的struct,然后按顺序访问,具体就不赘述了。类似的例子还有很多,但我认为如果仔细研究一下pcap库提取数据的方式,会对指针强制类型转换的理解有很大的帮助。
总之呢,指针也并非什么神秘之物,也没有人们说的那么难懂,关键就是一个地址的问题。我倒是认为C语言最闪光,最强大,最灵活的特性就是指针了。指针,C之魂也~!
C语言 Server和服务器之间的通信协议采用包头Header+包体Body的形式,能够具体实现这个吗?
当然可以,协议是具有层次的,协议的目的就是让通信双方能明白自己正在传输的是怎样的数据格式。
TCP/IP是一种比较通用的通信协议,在windows中采用socket组件库实现,是对协议通信功能的一种封装,
如你要发送一个信息(数据如“MSG”)从A到B,那么A将“MSG”打包成“4MSG”,第一个字节“4”表示这个数据包长度为4,那么接紧接的3个字节就是数据,那么这里就是一个协议,只是这个协议很简单,属于你自己开发的协议,而TCP这些协议属于开放协议,大家都知道标准,因此只要收到一个TCP数据包,那么你就可以根据协议分析你收到的数据包的格式是什么,数据包协议中,一般在数据包的开始部分定义了固定格式的信息,如TCP包头中包含了数据长度,目的的IP地址等很多信息。
如果你收到一个数据包,你不清楚它是什么格式的,那么你怎么解析呢,根本无法解析的,当然如果人工打开这个数据包进行数据内容与已知的协议比对,也许可以猜出它是什么格式。
看数据包的传送过程,
程序A:sengPackage("MSG"){ 调用TCP协议函数sendTCPPackage("4MSG");};
sendTCPPackage(char *pkg){调用IP协议函数sendIPPackage(TCP头+“4MSG”)};
sendIPPackage(char *pkg){调用MAC协议函数sendMACPackage(IP头+“TCP头+4MSG”)};
sendMACPackage(char *pkg){调用驱动发送数据包sendPkg(MAC头+“IP头TCP头+4MSG”)};
这里仅仅是用函数调用的描述解释协议实现的原理:协议的分层在编写程序时体现的就是一个调用层次关系。
在接收方,其实就是调用相同层级的函数对收到的数据包进行解包,把去掉本层头部的数据包传给上层调用函数,
如getPackage(char *buffer){
buffer = getTCPPackageData(buffer);
return buffer +1; // 去掉开始的一个字节。这里就是我自己定义的协议解包过程。
}; //buffer是收到的数据包。
char * getTCPPackage(char *buffer){
buffer = getIPPackageData(buffer);
buffer = 去掉TCP包后的数据包; // TCP包解包过程,IP,MAC的解包一样。
return buffer;
}
如HTTP是建立在TCP协议上,那么TCP包的数据部分就包含了HTTP的协议头部以及HTTP的数据部分。也就是说协议分层中,任何上层的协议被打包后的数据包(注意其中包含有协议头)被下层协议当做一个纯数据处理,下层协议并不清楚你上层怎么组织数据的。
因此我们只要能获得任何一层的协议调用函数接口,就可以采用该层协议来传输数据,我们如果能获得MAC层的调用函数接口,那么直接打包成MAC传输也可以,只是MAC的格式中不包含TCP、IP这些信息,数据包到达路由器的时候就不知道发给哪个电脑了,除非路由器知道MAC地址是哪个电脑,并且路由器支持MAC包的转发。因此需要用什么协议,是根据需要来确定的。
采用共用协议,目的是让通信过程更加通用,使系统可以通过已知的网络进行连接。
C# socket 接收数据包包括包头+数据
你说的这个就是涉及到通讯协议 也就是说 发送跟接受的数据规则
假定一次传输的数据固定长度 假设是100字节 那么 我们可以规定好 起始字节是2字节 数据字节是96字节后面是数据校验的2个字节 合计是100字节 那么你收到数据的时候 先获取除了最后2个字节的前98个字节 把这98个字节做对应的校验运算 与最后2个字节比对 发现是一样的 就说明数据有效 然后再把之前获取到的98个字节去掉前面2个字节 就是你需要的数据了
如何获取就要看你发送端是如何规定数据字节里面的规则了
本文名称:C语言判断数据包包头函数的简单介绍
当前URL:http://pwwzsj.com/article/heeihd.html