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函数得到路由表或列出所有已配置的接口. 数据链路 ...
随机推荐
- Xcode报错:Unexpected '@' in program
今天犯了个很弱的错误,就是当定义个一个@property时,编译器直接报错:Unexpected '@' in program 原因是把定义的属性写在.m文件中了,改到.h文件中就好了... 以后大家 ...
- VMware下打开Chrome OS遇到没有网络连接可用
打开ChromeOS.vmx文件,最后一行添加 ethernet0.virtualDev = "e1000" 就能解决.
- 矩阵分解(rank decomposition)文章代码汇总
矩阵分解(rank decomposition)文章代码汇总 矩阵分解(rank decomposition) 本文收集了现有矩阵分解的几乎所有算法和应用,原文链接:https://sites.goo ...
- 算法练习之:Doubles
Doubles Time Limit: 1000MS Memory Limit: 65536KB Problem Description As part of an arithmetic compet ...
- android文字阴影效果设置
<TextView android:id="@+id/tvText1" android:layout_width="wrap_content" andro ...
- 【HDOJ】2853 Assignment
最小费用最大流可解最优解.至于dif如何解,可以把w扩大100倍,如果mission编号和排列P相等则对w+1,然后建立网络流.对结果取模100可以得到没有改变mission的company数目,用c ...
- 33个优秀的HTML5应用演示 (转)
33个优秀的HTML5应用演示 (转) HTML5能做什么?取代Flash?制作动画?开发程序应用?这些都只是HTML5的一小部分功能而已. 大家可能听到很多关于Flash是否会被HTML5取代的讨论 ...
- java基于xml配置的通用excel单表数据导入组件(二、xml配置文件解析加载)
1.BN_ImportExcel.java 对应xml主节点属性 package XXXXX.manage.importexcel; import java.io.Serializable; impo ...
- 【转】Android:Animation的简单学习--不错
原文网址:http://blog.csdn.net/huangbiao86/article/details/6683665 Animation动画效果.提供了一系列的动画效果,可以应用大多数 的控件. ...
- 区别typedef和#define
1) #define是预处理指令,在编译预处理时进行简单的替换,不作正确性检查,不关含义是否正确照样带入,只有在编译已被展开的源程序时才会发现可能的错误并报错.例如:#define PI 3.1415 ...