郁闷的 原始UDP封包发送???
const
IP_OPTIONS = 1 ;{ set/get IP options }
IP_HDRINCL = 2 ;{ header is included with data }
IP_TOS = 3 ;{ IP type of service and preced}
IP_TTL = 4 ;{ IP time to live }
type
IPHeader=record // 20字节的IP头
iphVerLen :byte; // 版本号和头长度(各占4位)
ipTOS :byte; // 服务类型
ipLength :WORD; // 封包总长度,即整个IP报的长度
ipID :WORD; // 封包标识,惟一标识发送的每一个数据报
ipFlags :WORD; // 标志
ipTTL :byte; // 生存时间,就是TTL
ipProtocol :byte; // 协议,可能是TCP、UDP、ICMP等
ipChecksum :WORD; // 校验和
ipSource :Cardinal; // 源IP地址
ipDestination :Cardinal; // 目标IP地址
end;
PIPHeader=^IPHeader;
UDPHeader = record
sourcePort :WORD; // 源端口号
destinationPort :WORD; // 目的端口号
len :WORD; // 封包长度
checksum :WORD; // 校验和
end;
PUDPHeader=^UDPHeader;
....
function checksum(const Apc:PChar;Asize:integer):WORD;
var cksum:Cardinal;
buff:array of char;
Index:integer;
W:WORD;
b:byte;
begin
Result:=0;
SetLength(buff,Asize);
CopyMemory(buff,Apc,Asize);
cksum := 0;
Index:=0;
while (Asize>1) do
begin
CopyMemory(@W,@buff[Index],sizeof(W));
cksum := cksum + W;
Asize := Asize - sizeof(WORD);
Index := Index + sizeof(WORD);
end;
// 是奇数
if (Asize mod 2)<>0 then
begin
CopyMemory(@b,@buff[Index],sizeof(b));
cksum:=cksum + b;
end;
// 将32位的chsum高16位和低16位相加,然后取反
cksum:=HIWORD(cksum)+LOWORD(cksum);
cksum:=not cksum;
Result:=cksum;
end;
{
计算UDP伪头校验和。UDP校验和基于如下几个域:
源IP地址
目的IP地址
8位0域
8位协议域
16位UDP长度
16位源端口号
16位目的端口号
16位UDP封包长度
16位UDP校验和(0)
UDP净荷
}
procedure ComputeUdpPseudoHeaderChecksum(
pIphdr:PIPHeader;
pUdphdr:PUDPHeader;
payload:PChar;
payloadlen:integer);
var buff:array[0..1023] of char;
ptr:PChar;
chksumlen:integer;
zero:ULONG;
i:integer;
begin
ptr:=@buff;
chksumlen := 0;
zero := 0;
// 包含源IP地址和目的IP地址
CopyMemory(ptr,@pIpHdr.ipSource,sizeof(pIpHdr.ipSource));
ptr:=ptr+sizeof(pIphdr.ipSource);
chksumlen :=chksumlen+ sizeof(pIphdr.ipSource);
CopyMemory(ptr, @pIphdr.ipDestination, sizeof(pIphdr.ipDestination));
ptr :=ptr + sizeof(pIphdr.ipDestination);
chksumlen :=chksumlen + sizeof(pIphdr.ipDestination);
// 包含8位0域
CopyMemory(ptr, @zero, 1);
ptr :=ptr + 1;
chksumlen := chksumlen + 1;
// 协议
CopyMemory(ptr, @pIphdr.ipProtocol, sizeof(pIphdr.ipProtocol));
ptr := ptr + sizeof(pIphdr.ipProtocol);
chksumlen := chksumlen + sizeof(pIphdr.ipProtocol);
// UDP长度
CopyMemory(ptr, @pUdphdr.len, sizeof(pUdphdr.len));
ptr :=ptr + sizeof(pUdphdr.len);
chksumlen :=chksumlen + sizeof(pUdphdr.len);
// UDP源端口号
CopyMemory(ptr, @pUdphdr.sourcePort, sizeof(pUdphdr.sourcePort));
ptr := ptr + sizeof(pUdphdr.sourcePort);
chksumlen := chksumlen + sizeof(pUdphdr.sourcePort);
// UDP目的端口号
CopyMemory(ptr, @pUdphdr.destinationPort, sizeof(pUdphdr.destinationPort));
ptr :=ptr + sizeof(pUdphdr.destinationPort);
chksumlen := chksumlen + sizeof(pUdphdr.destinationPort);
// 又是UDP长度
CopyMemory(ptr, @pUdphdr.len, sizeof(pUdphdr.len));
ptr := ptr + sizeof(pUdphdr.len);
chksumlen := chksumlen + sizeof(pUdphdr.len);
// 16位的UDP校验和,置为0
CopyMemory(ptr, @zero, sizeof(WORD));
ptr :=ptr + sizeof(WORD);
chksumlen :=chksumlen + sizeof(WORD);
// 净荷
CopyMemory(ptr, payload, payloadlen);
ptr :=ptr + payloadlen;
chksumlen :=chksumlen + payloadlen;
// 补齐到下一个16位边界
for i:=0 to payloadlen div 2 do
begin
ptr^ := chr(0);
ptr:=ptr + 1;
chksumlen:=chksumlen+1;
end;
// 计算这个校验和,将结果填充到UDP头
pUdphdr.checksum := checksum(PChar(@buff), chksumlen);
end;
procedure TForm1.Button10Click(Sender: TObject);
var bIncl:bool;// 即 longbool;
buff:array[0..1023] of char;
pIpHdr:PIPHeader;
pUdpHdr:PUDPHeader;
destAddr:SOCKADDR_IN;
nRet:integer;
s,szSourceIp,szDestIp:string;
nDestPort,nSourcePort:WORD;
pData:PChar;
begin
ZeroMemory(@buff,1024);
szSourceIp:='192.168.2.137';
szDestIp:='192.168.2.1';
nDestPort:=53;
nSourcePort:=1101;
s:=#$00+#$02 +#$01+#$00 +#$00+#$01 +#$00+#$00 +#$00+#$00 +#$00+#$00
+#$03 +'www' +#$03 +'163' +#$03 +'com' +#$00+#$00 +#$01+#$00 +#$01;
Memo1.Lines.Add('length(s) : '+inttostr(length(s)));
rawSocket:=socket(AF_INET,SOCK_RAW,IPPROTO_UDP);
bIncl:=true;
setsockopt(rawSocket,IPPROTO_IP,IP_HDRINCL,PChar(@bIncl),sizeof(bIncl));
pIpHdr:=PIPHeader(@buff);
pIpHdr.iphVerLen:= 4 shl 4 or (sizeof(IPHeader) div sizeof(ULONG));
pIpHdr.ipLength:=htons(sizeof(IPHeader)+sizeof(UDPHeader)+length(s));
pIpHdr.ipTTL:=128;
pIpHdr.ipProtocol:=IPPROTO_UDP;
pIpHdr.ipSource:=inet_addr(PChar(szSourceIp));
pIpHdr.ipDestination:=inet_addr(PChar(szDestIp));
pIpHdr.ipChecksum:=checksum(PChar(pIpHdr),sizeof(IPHeader));
Memo1.Lines.Add('pIpHdr.ipChecksum : '+inttostr(pIpHdr.ipChecksum));
pUdpHdr:=PUDPHeader(@buff[sizeof(IPHeader)]);
pUdpHdr.sourcePort:=htons(nSourcePort);
pUdpHdr.destinationPort:=htons(nDestPort);
pUdpHdr.len:=htons(sizeof(UDPHeader)+length(s));
pUdpHdr.checksum:=0;
pData:=@buff[sizeof(IPHeader)+sizeof(UDPHeader)];
CopyMemory(pData,PChar(s),length(s));
ComputeUdpPseudoHeaderChecksum(pIpHdr,pUdpHdr,pData,length(s));
Memo1.Lines.Add('pUdpHdr.checksum : '+inttostr(pUdpHdr.checksum));
ZeroMemory(@destAddr,sizeof(SOCKADDR_IN));
destAddr.sin_family:=AF_INET;
destAddr.sin_port:=htons(nDestPort);
destAddr.sin_addr.S_addr:=inet_addr(PChar(szDestIp));
nRet:=sendto(rawSocket,buff,sizeof(IPHeader)+sizeof(UDPHeader)+length
(s),0,destAddr,sizeof(destAddr));
if nRet=SOCKET_ERROR then
begin
nRet:=WSAGetLastError;
memo1.Lines.Add('Send failed : '+inttostr(nRet));
end
else
Memo1.Lines.Add('Send '+inttostr(nRet)+' bytes');
CloseSocket(rawSocket);
end;点击 Button10 ,打印出:
length(s) : 29
pIpHdr.ipChecksum : 55732
pUdpHdr.checksum : 8523
Send failed : 10049但是 C++ 代码,运行是 OK的。
查了 好久,查不出Delphi代码出错的原因,请指教。
PS:长度 原因,C++代码 与楼下 贴出。
相关推荐
郁闷的原始UDP封包
郁闷的原始UDP封包,无话说.......................................................
WildPackets OmniPeek从入门到郁闷之入门篇.pdf
WildPackets OmniPeek从入门到郁闷之入门篇.pdf
易语言-易语言http socks4 socks5 超级代理服务端
基于 hp-socket 开发的代理服务器, 多连接,速度非常的快 可基于一个端口开放 HTTP 和 SOCKS4 和 SOCKS5 的代理协议 支持 HTTPS 连接 HTTP 和 SOCKS4 比较简单 只是单纯的转发 这次增加了 SOCKS5 协议 SOCKS5 协议支持:匿名或帐号密码方式的验证,远程解析域名,UDP 协议。 做 UDP 的时候本来想 HP 的 UDP 库,后来发现并不怎么用好用,所以就自己用 API 写了个便携的 UDP 功能 基本上可以满足使用,并且还方便。至于性能没太怎么测试,(只是代理了一下 QQ 测试了下,没什么问题) 代码都是参考网上的协议文档写的,可能会有一些逻辑上的判断问题 至于性能和稳定性,上个版本还比较稳定,这次也就用 QQ 旺旺 浏览器 做了下局域网的测试 有人问要怎么使用,我也是郁闷了,这是服务端,只提供服务,我也说明下吧。 此处是代理的端口号,自己修改成需要的就行,然后启动程序,再需要使用代理的程序里设置下代理信息。 这是在QQ上设置的,其他的程序不会设置就百度下。 如果要外网使用可能需要在路由上做下端口映射了,调试的时候会输出一些连接的信息,和错误提示,有问题可以找我问问
易语言实现超级代理服务端源码,支持http socks4 socks5 -易语言
基于 hp-socket 开发的代理服务器, 多连接,速度非常的快 可基于一个端口开放 HTTP 和 SOCKS4 和 SOCKS5 的代理协议 支持 HTTPS 连接 HTTP 和 SOCKS4 比较简单 只是单纯的转发 这次增加了 SOCKS5 协议 SOCKS5 协议支持:匿名或帐号密码方式的验证,远程解析域名,UDP 协议。 做 UDP 的时候本来想 HP 的 UDP 库,后来发现并不怎么用好用,所以就自己用 API 写了个便携的 UDP 功能 基本上可以满足使用,并且还方便。至于性能没太怎么测试,(只是代理了一下 QQ 测试了下,没什么问题) 代码都是参考网上的协议文档写的,可能会有一些逻辑上的判断问题 至于性能和稳定性,上个版本还比较稳定,这次也就用 QQ 旺旺 浏览器 做了下局域网的测试 有人问要怎么使用,我也是郁闷了,这是服务端,只提供服务,我也说明下吧。 此处是代理的端口号,自己修改成需要的就行,然后启动程序,再需要使用代理的程序里设置下代理信息。 这是在QQ上设置的,其他的程序不会设置就百度下。 如果要外网使用可能需要在路由上做下端口映射了,调试的时候会输出一些连接的信息,和错误提示,有问题可以找我问问
蓄电池储能并网发电系统充放电+网侧变流器PQ控制【仿真+参考文献】
内容概要:本文针对含分布式电源的配电网在多线路故障情况下的恢复问题,提出了一种将网络重构、孤岛划分与检修进度统一纳入多时段优化框架的故障恢复模型。该模型以最小化网损和甩负荷惩罚为目标,综合考虑节点功率守恒、支路潮流、电压与容量限制、二阶锥松弛以及拓扑连通性等约束条件,通过引入虚拟流方法保证各供电片区的内部连通,并借助大常数松弛处理断开支路,实现了故障后逐时段的最优恢复方案制定。模型在IEEE33节点系统上进行了仿真验证,展示了各时段的网络拓扑变化、节点电压分布及负荷恢复情况,证明了其在提升系统韧性方面的有效性。同时,文章还对现有模型在负荷分级、无功处理、辐射状结构描述等方面的不足提出了改进建议。; 适合人群:电力系统自动化、智能电网及相关专业的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究配电网在极端事件下的弹性恢复能力;②设计含分布式电源的主动配电网故障后网络重构与孤岛运行协同策略;③优化多时段故障恢复过程中开关操作序列与负荷恢复优先级;④为学术论文撰写或工程项目提供理论基础和技术参考。; 阅读建议:此资源以数学规划方法为核心,侧重于建模思想与实现细节,读者应结合文中列出的参考文献深入理解虚拟流、二阶锥松弛等关键技术的应用背景,并通过复现仿真案例来掌握模型的具体构建与求解流程,进而针对实际需求进行扩展和完善。


网络通信/分布式开发

