UDP 校检和和算法
#include <Winsock2.h> #include <stdio.h> #define IP_HDRINCL 2 // Header is included with data. typedef struct _IPHEADER { UCHAR VerHeadLen; //版本号和头长度 UCHAR TOS; //服务类型 USHORT Length; //IP包总长度 USHORT ID; //IP包唯一标识 USHORT Flags; //标志 UCHAR TTL; //生存时间 UCHAR Protocol; //协议 USHORT Checksum; //校验和 ULONG SourceIP; //源IP地址 ULONG DestIP; //目标IP }IPHEADER; typedef struct _UDPHEADER { USHORT SourcePort; //源端口 USHORT DestPort; //目的端口 USHORT Length; //包长度 USHORT CheckSum; //校验和 }UDPHEADER; USHORT checksum(USHORT * buff, int size) { ULONG cksum = 0; while (size > 1) { cksum += *(buff++); size -= sizeof(USHORT); } if(size) { cksum += *((UCHAR*)buff); } cksum = (cksum >> 16) + (cksum & 0xffff); cksum += (cksum >> 16); return (USHORT)(~cksum); } void UdpHeaderChecksum(IPHEADER *IpHeader,UDPHEADER *UdpHeader,char * payload,int payloadlen) { char buf[1024]; char *ptr = buf; int chksumlen = 0; ULONG zero = 0; //包含源IP地址和目的IP地址 memcpy(ptr,&IpHeader->SourceIP,sizeof(IpHeader->SourceIP)); ptr += sizeof(IpHeader->SourceIP); chksumlen += sizeof(IpHeader->SourceIP); memcpy(ptr,&IpHeader->DestIP,sizeof(IpHeader->DestIP)); ptr += sizeof(IpHeader->DestIP); chksumlen += sizeof(IpHeader->DestIP); //8位0域 memcpy(ptr,&zero,1); ptr += 1; chksumlen += 1; //协议 memcpy(ptr,&IpHeader->Protocol,sizeof(IpHeader->Protocol)); ptr += sizeof(IpHeader->Protocol); chksumlen += sizeof(IpHeader->Protocol); //UDP长度 memcpy(ptr,&UdpHeader->Length,sizeof(UdpHeader->Length)); ptr += sizeof(UdpHeader->Length); chksumlen += sizeof(UdpHeader->Length); //UDP端口号 memcpy(ptr,&UdpHeader->SourcePort,sizeof(UdpHeader->SourcePort)); ptr += sizeof(UdpHeader->SourcePort); chksumlen += sizeof(UdpHeader->SourcePort); memcpy(ptr,&UdpHeader->DestPort,sizeof(UdpHeader->DestPort)); ptr += sizeof(UdpHeader->DestPort); chksumlen += sizeof(UdpHeader->DestPort); //UDP长度 memcpy(ptr,&UdpHeader->Length,sizeof(UdpHeader->Length)); ptr += sizeof(UdpHeader->Length); chksumlen += sizeof(UdpHeader->Length); //16位UDP校验和 memcpy(ptr,&zero,sizeof(UdpHeader->CheckSum)); ptr += sizeof(USHORT); chksumlen += sizeof(USHORT); //净荷 memcpy(ptr,payload,payloadlen); ptr += payloadlen; chksumlen += payloadlen; //补齐到下一个16位边界 for(int i = 0; i < payloadlen %2; i++) { *ptr = 0; ptr++; chksumlen++; } //计算校验和,填充到UDP头 UdpHeader->CheckSum = checksum((USHORT*)buf,chksumlen); } int main() { int i = 0; WSADATA wsaData; int wsaret = WSAStartup(0x101,&wsaData); if(wsaret != 0) { printf("WSAStartup失败\n"); } char szDestIP[] = "192.168.12.110"; char szSourceIP[] = "192.168.12.169"; USHORT nDestPort = 1234; USHORT nSourcePort = 8888; char szMsg[] = "123456"; int nMsgLen = strlen(szMsg); //创建原始套接字 SOCKET sRaw = ::socket(AF_INET,SOCK_RAW,IPPROTO_UDP); //有效IP头包含选项 BOOL bIncl = TRUE; i = ::setsockopt(sRaw,IPPROTO_IP,IP_HDRINCL,(char*)&bIncl,sizeof(bIncl)); char buff[1024] = {0}; int TotalLength = sizeof(IPHEADER) + sizeof(UDPHEADER) + nMsgLen; //IP头 IPHEADER * IpHeader = (IPHEADER*)buff; IpHeader->VerHeadLen = (4 << 4 | (sizeof(_IPHEADER)/sizeof(ULONG))); IpHeader->Length = TotalLength; IpHeader->TTL = 128; IpHeader->Protocol = IPPROTO_UDP; IpHeader->SourceIP = ::inet_addr(szSourceIP); IpHeader->DestIP = ::inet_addr(szDestIP); IpHeader->Checksum = checksum((USHORT*)IpHeader,sizeof(IPHEADER)); //UDP头 UDPHEADER * UdpHeader = (UDPHEADER*)(buff + sizeof(IPHEADER)); UdpHeader->SourcePort = htons(nSourcePort); UdpHeader->DestPort = htons(nDestPort); UdpHeader->Length = htons(sizeof(UDPHEADER) + nMsgLen); UdpHeader->CheckSum = 0; UdpHeaderChecksum(IpHeader,UdpHeader,szMsg,nMsgLen); char* pData = buff + sizeof(IPHEADER) + sizeof(UDPHEADER); memcpy(pData,szMsg,nMsgLen); //设置目的地址 SOCKADDR_IN Addr = {0}; Addr.sin_family = AF_INET; Addr.sin_port = htons(nDestPort); memset(Addr.sin_zero,0,8); Addr.sin_addr.S_un.S_addr = ::inet_addr(szDestIP); //发送原始UDP封包 int nRet = 0; for(i = 0; i < 5; i++) { nRet = sendto(sRaw,buff,TotalLength,0,(sockaddr*)&Addr,sizeof(sockaddr)); if(nRet == SOCKET_ERROR) { printf("sendto() faild:%d\n",WSAGetLastError()); break; } else { printf("send %d bytes\n",nRet); } } closesocket(sRaw); return 0; } 刚开始时,服务程序根本接收不到我发的包,用ethereal抓包时发现数据确实是发送出去了,但显示信息表示UDP校验和不正确。 后来发现计算UDP校验和时,我把IP头也计算进去,实际上,UDP的校验和只需要计算从UDP头开始到后面的净荷。 找到问题后觉得十分简单,但如果有些朋友也犯了和我一样的错误的话,希望有所帮助
UDP 校检和和算法的更多相关文章
- SQL Server ->> 校检函数CHECKSUM、CHECKSUM_AGG、BINARY_CHECKSUM和HASHBYTES
今天特地查了一下SQL Server下的校检函数有哪些.原本我只是在工作中用过一个CHECKSUM,今天特地学习了一下才发现原来还有其他的校检函数. 这里找到了别人对于SQL SERVER下这几个校检 ...
- Spring MVC全局异常处理与拦截器校检
在使用Spring MVC进行开发时,总是要对系统异常和用户的异常行为进行处理,以提供给用户友好的提示,也可以提高系统的安全性. 拦截系统响应错误 首先是拦截系统响应错误,这个可以在web.xml中配 ...
- TableView 校检表
这俩天学习了tableView 校检表 主要就是通过一个方法来跟踪当前选中的行.下面将声明一个NSIndexPath 的属性来跟踪最后选中的行.这篇文章希望能给那些初学者带来学习的乐趣.不说了直接上代 ...
- TCP粘包, UDP丢包, nagle算法
一.TCP粘包 1. 什么时候考虑粘包 如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议,UDP不会出 ...
- 四则运算生成与校检 Python实现
GitHub地址 https://github.com/little-petrol/Arithmetic.git 合作者: 郭旭 和 卢明凯 设计实现过程 代码的组织主要分为两个部分: 算法与结构体的 ...
- 表单数据校检方法 onsubmit()的使用?
在项目中为一个表单(from)编写onsubmit()脚本的时候,经常需要验证表单中数据的合法性 所以常会写道:<form action="/admin/addUser.do" ...
- 批处理--md5校检
@echo off rem 获取文件xx.zip的MD5 for /f "delims=" %%i in ('md5.exe xx.zip') do (set md5_var=%% ...
- Java 中使用正则表达式校检IP是否输入正确
感谢大佬案例:https://www.jb51.net/article/114671.htm 正则表达式学习:(待办)近期总结
- UNP学习笔记(第十八章 路由套接字)
路由套接字上支持3种类型的操作 1). 进程能通过写路由套接字向内核发消息. 2). 进程能通过路由套接字从内核读消息. 3). 进程可以用sysctl函数得到路由表或列出所有已配置的接口. 数据链路 ...
随机推荐
- [Leetcode] Validate BST
给一个Binary Tree,检查是不是Binary Search Tree. 即是否满足对每个节点,左子树的中的所有节点的值 < 当前节点的值 < 右子树所有节点的值. Solution ...
- OneAlert 入门(三)——事件分析
OneAlert 是国内首个 SaaS 模式的云告警平台,集成国内外主流监控/支撑系统,实现一个平台上集中处理所有 IT 事件,提升 IT 可靠性.有了 OneAlert,你可以更快更合理地为事件划分 ...
- Android的Handler总结
一.Handler的定义: 主要接受子线程发送的数据, 并用此数据配合主线程更新UI. 解释: 当应用程序启动时,Android首先会开启一个主线程 (也就是U ...
- MySQL查询原理及其慢查询优化案例分享(转)
MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓“好马配好鞍”,如何能够更 好的使用它,已经成为开发工程师的必修课,我们经常会从职 ...
- 【HDOJ】3466 Proud Merchants
先排序预处理,后01背包. #include <stdio.h> #include <string.h> #include <stdlib.h> #define M ...
- scp 在不同主机之间数据传输
不同的Linux之间copy文件常用有3种方法,第一种就是ftp,也就是其中一台Linux安装ftp Server,这样可以另外一台使用ftp的client程序来进行文件的copy.第二种方法就是采用 ...
- selenium webdriver(2)---页面对象定位
webdriver的元素定位很灵活,提供了多种定位方式: Id LinkText PartialLinkText Name TagName Xpath ClassName CssSelector 这些 ...
- JavaScript---网络编程(10)--DHTML技术演示(3)-多选框
这节讲述多选框的使用,当然,肯定是结合css和Javascript一起的. checkbox的使用1: 演示代码: <html> <head> <meta http-eq ...
- 如何解决PHP生成UTF-8编码的CSV文件用Excel打开乱码的问题
为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE字符开头.这作为一个”特征符”或”字节顺序标记(byte-o ...
- Bzoj 3505: [Cqoi2014]数三角形 数论
3505: [Cqoi2014]数三角形 Time Limits: 1000 ms Memory Limits: 524288 KB Detailed Limits Description