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函数得到路由表或列出所有已配置的接口. 数据链路 ...
随机推荐
- poj 1273
网络流之最大流的基础题: 可以使用dinic算法和EK算法: 分别对着模板敲了一遍: dinic: #include<cstdio> #include<cstring> #in ...
- 需要插入子集的时候如何更新父级ID
场景模拟: 我们需要在不同的新闻站点中采集新闻信息, 所以需要在数据库中保存一个新闻站点表(Site) 一个新闻表(News) 两表之间的关系是 Site(1)-News(N) 数据库 ...
- Wild Words
poj1816:http://poj.org/problem?id=1816 题意:给你n个模板串,然后每个串除了字母,还有?或者*,?可以代替任何非空单个字符,*可以替代任何长度任何串,包括空字符串 ...
- 子查询解嵌套not in 无法展开改写
SQL> explain plan for select * from OPS$CZTEST1.SAVJ_ATOMJOURBAK where ((list_flag = '1' and prt_ ...
- oracle core 概述
oracle数据库系统的架构及其复杂,其提供的特性也非常的多.作为一种关系型数据库,oracle提供的基本特性: transaction concurrency read consistent 而支撑 ...
- Remarks on a preprint
Page 2 Line 1, "reads" should be "read". Page 2 Line 5, "are initial veloci ...
- .NET混淆工具 (Dotfuscator Professional Edition)
如果不想自己辛辛苦苦码出来的作品被人轻易的破解cpoy就使用这款工具试试吧.^_^ 使用版本:4.9.7500.9484 ,破解版:http://pan.baidu.com/s/1dDH7lr ...
- Selenium WebDriver + Grid2 + RSpec之旅(二)----Grid2的配置
Selenium WebDriver + Grid2 + RSpec之旅(二) ----Grid2的配置 为什么要使用Selenium-Grid 分布式运行大规模的TestCase 能够通过一个中央节 ...
- 用户故事(User Story)
摘要: 一件用户通过系统完成他一个有价值的目标(买一罐饮料)的事.这样的过程就叫“用户案例(user case)”或者“用户故事(user story)”.本文描述了敏捷开发的技巧:如何以用户故事管理 ...
- 分布式基础通信协议:paxos,totem和gossip
转:http://blog.csdn.net/cloudresearch/article/details/23127985 背景: 在分布式中,最难解决的一个问题就是多个节点间数据同步问题.为了解决这 ...