我想往局域网内的另一台电脑发送一个自定义的IP包。同样的程序,用C写了一份,又用Delphi写了一份,为什么Delphi发不出去,而用VC写的却没有问题?每次SendTo返回,都是SOCKET_ERROR。我检查过所生成的包,没有问题,就是缓冲中的内容无法通过SendTo发送出去。我的环境是WIN2000,Delphi7。
////////////Delphi版的///////////////////////////
uses WinSock,IdWinSock2 使用了这2个库
///////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
iErrorCode:integer;
wsd:TWSADATA ;
s:TSocket;
ip_header:IPHeader;
tcp_header:_TCPHeader;
psd_header:_PSD_HEADER;
remote:sockaddr_in;
ptr:PByte;
bOpt:integer;
iTotalSize:WORD;
iTCPSize:WORD;
sendBuf:pByte;
srcPort,destPort:WORD;
iAck:Cardinal;
begin
if WSAStartup(MAKEWORD(2,2),wsd)=0 then
begin
s:=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if s<>INVALID_SOCKET then
begin
bOpt:=1;
iErrorCode:=setsockopt(s,IPPROTO_IP,IP_HDRINCL,@bOpt,sizeof(bOpt));
if iErrorCode<>SOCKET_ERROR then
begin
iTotalSize:=44;
iTCPSize:=24;
GetMem(sendBuf,iTotalSize);
ip_header.h_lenver:=(4 shl 4 or sizeof(ip_header) div sizeof(Cardinal));
ip_header.total_len:=htons(iTotalSize);
ip_header.tos:=0;
ip_header.ident:=htons(17393);
ip_header.frag_and_flags:=0;
ip_header.ttl:=57;
ip_header.proto:=IPPROTO_TCP;
ip_header.checksum:=0;
ip_header.sourceIP:=inet_addr('192.168.1.2');
ip_header.destIP:=inet_addr('192.168.1.3');
ip_header.checksum:=checksum(pWord(@ip_header),20);
//////////////////////////////////////////////////////////////
srcPort:=80;
DestPort:=1300;
iAck:=132100121;
tcp_header.th_sport:=htons(srcPort);
tcp_header.th_dport:=htons(destPort);
tcp_header.th_seq:=htonl($581A784D);
tcp_header.th_ack:=htonl(iAck+1);
tcp_header.th_lenres:=(iTCPSize div sizeof(Cardinal) shl 4 or 0);
tcp_header.th_flag:=$12;
tcp_header.th_win:=htons(65535);
tcp_header.th_urp:=0;
tcp_header.th_sum:=0;
///////////////////////////////////////////////////
psd_header.saddr:=ip_header.sourceIP;
psd_header.daddr:=ip_header.destIP;
psd_header.mbz:=0;
psd_header.ptcl:=IPPROTO_TCP;
psd_header.tcpl:=htons(iTCPSize);
ZeroMemory(sendBuf,iTotalSize);
///////////////////////////////////////////////////
CopyMemory(sendBuf,@psd_header,sizeof(psd_header));
ptr:=sendBuf;
inc(ptr,sizeof(psd_header));
CopyMemory(ptr,@tcp_header,sizeof(tcp_header));
inc(ptr,sizeof(tcp_header));
ptr^:=$02;
inc(ptr);
ptr^:=$04;
inc(ptr);
ptr^:=$05;
inc(ptr);
ptr^:=$b4;
tcp_header.th_sum:=checksum(pWord(sendBuf),sizeof(psd_header)+24);
ZeroMemory(sendBuf,iTotalSize);
////////////////////////////////////////////////////
CopyMemory(sendBuf,@ip_header,sizeof(ip_header));
ptr:=sendBuf;
inc(ptr,sizeof(ip_header));
CopyMemory(ptr,@tcp_header,sizeof(tcp_header));
ptr:=sendBuf;
inc(ptr,sizeof(ip_header)+sizeof(tcp_header));
ptr^:=$02;
inc(ptr);
ptr^:=$04;
inc(ptr);
ptr^:=$05;
inc(ptr);
ptr^:=$b4;
remote.sin_family:= AF_INET;
remote.sin_port:= htons(destPort);
remote.sin_addr.s_addr:= inet_addr('192.168.1.3');
iErrorCode:=sendto(s,sendBuf,iTotalSize,0,@remote,sizeof(remote));//就是执行到这
//返回为SOCKET_ERROR
if iErrorCode<>SOCKET_ERROR then
begin
iTotalSize:=40;
iTCPSize:=20;
CloseSocket(s);
FreeMem(sendBuf);
end;
end;
end;
end;
end;
//////////////////////////////////////////////////////////////////////VC++版//////////////////////////////////////
#include <winsock2.h>
#include <ws2tcpip.h>
///////////////////////////////////////////////////////
void CTest1Dlg::sendTCP_SYNACK(char *szSrcIP, char *szDestIP, unsigned short srcPort, unsigned short destPort, unsigned int iAck)
{ int iErrorCode;
WSADATA wsd;
SOCKET s;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
PSD_HEADER psd_header;
struct sockaddr_in remote;
char * ptr=NULL;
//创建socket
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
return; s=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (s==INVALID_SOCKET)
return;
BOOL bOpt = TRUE;
iErrorCode = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
if (iErrorCode==SOCKET_ERROR)
{
closesocket(s);
return;
}
//---end-
//伪装连接
unsigned short iTotalSize=44;
unsigned short iTCPSize=24;
char *sendBuf=new char[iTotalSize]; ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位版本号,低四位首部长度
ip_header.total_len=htons(iTotalSize); //16位总长度
ip_header.tos=0;
ip_header.ident=htons(17393);
ip_header.frag_and_flags=0;
ip_header.ttl=57;
ip_header.proto=IPPROTO_TCP;
ip_header.checksum=0; //16位校验和
ip_header.sourceIP=inet_addr(szSrcIP); //32位远地址·
ip_header.destIP=inet_addr(szDestIP); //32位目的地址·
ip_header.checksum=checksum((USHORT *)&ip_header,20);
//填充TCP首部
tcp_header.th_sport=htons(srcPort); //源端口
tcp_header.th_dport=htons(destPort); //目的端口
tcp_header.th_seq=htonl(0x581A784D); //SYN序列号
tcp_header.th_ack=htonl(iAck+1); //应答序号
tcp_header.th_lenres=(iTCPSize/sizeof(unsigned long)<<4|0); //TCP长度和保留位
tcp_header.th_flag=0x12; //SYN 标志
tcp_header.th_win=htons(65535); //窗口大小
tcp_header.th_urp=0; //紧急指针
tcp_header.th_sum=0; //校验和
//填充TCP伪首部(只用于生成校验和)
psd_header.saddr=ip_header.sourceIP;
psd_header.daddr=ip_header.destIP;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(iTCPSize);
ZeroMemory(sendBuf,iTotalSize);
//计算tcp校验和,包含伪TCP header
memcpy(sendBuf,&psd_header,sizeof(psd_header));
ptr=sendBuf+sizeof(psd_header);
memcpy(ptr,&tcp_header,sizeof(tcp_header));
ptr=sendBuf+sizeof(psd_header)+sizeof(tcp_header);
*ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
tcp_header.th_sum=checksum((USHORT *)sendBuf,sizeof(psd_header)+24);
ZeroMemory(sendBuf,iTotalSize);
//填充发送缓冲区
memcpy(sendBuf,&ip_header,sizeof(ip_header));
ptr=sendBuf+sizeof(ip_header);
memcpy(ptr,&tcp_header,sizeof(tcp_header));
ptr=sendBuf+sizeof(ip_header)+sizeof(tcp_header);
*ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
remote.sin_family = AF_INET;
remote.sin_port = htons(destPort);
remote.sin_addr.s_addr = inet_addr(szDestIP);
iErrorCode = sendto(s, sendBuf, iTotalSize, 0, (SOCKADDR *)&remote, sizeof(remote));
if(iErrorCode==SOCKET_ERROR)
return;
iTotalSize=40;
iTCPSize=20;
// end--------
closesocket(s);
delete[] sendBuf;
return;
}
////////////Delphi版的///////////////////////////
uses WinSock,IdWinSock2 使用了这2个库
///////////////////////////////////////////////
procedure TForm1.Button1Click(Sender: TObject);
var
iErrorCode:integer;
wsd:TWSADATA ;
s:TSocket;
ip_header:IPHeader;
tcp_header:_TCPHeader;
psd_header:_PSD_HEADER;
remote:sockaddr_in;
ptr:PByte;
bOpt:integer;
iTotalSize:WORD;
iTCPSize:WORD;
sendBuf:pByte;
srcPort,destPort:WORD;
iAck:Cardinal;
begin
if WSAStartup(MAKEWORD(2,2),wsd)=0 then
begin
s:=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if s<>INVALID_SOCKET then
begin
bOpt:=1;
iErrorCode:=setsockopt(s,IPPROTO_IP,IP_HDRINCL,@bOpt,sizeof(bOpt));
if iErrorCode<>SOCKET_ERROR then
begin
iTotalSize:=44;
iTCPSize:=24;
GetMem(sendBuf,iTotalSize);
ip_header.h_lenver:=(4 shl 4 or sizeof(ip_header) div sizeof(Cardinal));
ip_header.total_len:=htons(iTotalSize);
ip_header.tos:=0;
ip_header.ident:=htons(17393);
ip_header.frag_and_flags:=0;
ip_header.ttl:=57;
ip_header.proto:=IPPROTO_TCP;
ip_header.checksum:=0;
ip_header.sourceIP:=inet_addr('192.168.1.2');
ip_header.destIP:=inet_addr('192.168.1.3');
ip_header.checksum:=checksum(pWord(@ip_header),20);
//////////////////////////////////////////////////////////////
srcPort:=80;
DestPort:=1300;
iAck:=132100121;
tcp_header.th_sport:=htons(srcPort);
tcp_header.th_dport:=htons(destPort);
tcp_header.th_seq:=htonl($581A784D);
tcp_header.th_ack:=htonl(iAck+1);
tcp_header.th_lenres:=(iTCPSize div sizeof(Cardinal) shl 4 or 0);
tcp_header.th_flag:=$12;
tcp_header.th_win:=htons(65535);
tcp_header.th_urp:=0;
tcp_header.th_sum:=0;
///////////////////////////////////////////////////
psd_header.saddr:=ip_header.sourceIP;
psd_header.daddr:=ip_header.destIP;
psd_header.mbz:=0;
psd_header.ptcl:=IPPROTO_TCP;
psd_header.tcpl:=htons(iTCPSize);
ZeroMemory(sendBuf,iTotalSize);
///////////////////////////////////////////////////
CopyMemory(sendBuf,@psd_header,sizeof(psd_header));
ptr:=sendBuf;
inc(ptr,sizeof(psd_header));
CopyMemory(ptr,@tcp_header,sizeof(tcp_header));
inc(ptr,sizeof(tcp_header));
ptr^:=$02;
inc(ptr);
ptr^:=$04;
inc(ptr);
ptr^:=$05;
inc(ptr);
ptr^:=$b4;
tcp_header.th_sum:=checksum(pWord(sendBuf),sizeof(psd_header)+24);
ZeroMemory(sendBuf,iTotalSize);
////////////////////////////////////////////////////
CopyMemory(sendBuf,@ip_header,sizeof(ip_header));
ptr:=sendBuf;
inc(ptr,sizeof(ip_header));
CopyMemory(ptr,@tcp_header,sizeof(tcp_header));
ptr:=sendBuf;
inc(ptr,sizeof(ip_header)+sizeof(tcp_header));
ptr^:=$02;
inc(ptr);
ptr^:=$04;
inc(ptr);
ptr^:=$05;
inc(ptr);
ptr^:=$b4;
remote.sin_family:= AF_INET;
remote.sin_port:= htons(destPort);
remote.sin_addr.s_addr:= inet_addr('192.168.1.3');
iErrorCode:=sendto(s,sendBuf,iTotalSize,0,@remote,sizeof(remote));//就是执行到这
//返回为SOCKET_ERROR
if iErrorCode<>SOCKET_ERROR then
begin
iTotalSize:=40;
iTCPSize:=20;
CloseSocket(s);
FreeMem(sendBuf);
end;
end;
end;
end;
end;
//////////////////////////////////////////////////////////////////////VC++版//////////////////////////////////////
#include <winsock2.h>
#include <ws2tcpip.h>
///////////////////////////////////////////////////////
void CTest1Dlg::sendTCP_SYNACK(char *szSrcIP, char *szDestIP, unsigned short srcPort, unsigned short destPort, unsigned int iAck)
{ int iErrorCode;
WSADATA wsd;
SOCKET s;
IP_HEADER ip_header;
TCP_HEADER tcp_header;
PSD_HEADER psd_header;
struct sockaddr_in remote;
char * ptr=NULL;
//创建socket
if (WSAStartup(MAKEWORD(2,2), &wsd) != 0)
return; s=socket(AF_INET, SOCK_RAW, IPPROTO_IP);
if (s==INVALID_SOCKET)
return;
BOOL bOpt = TRUE;
iErrorCode = setsockopt(s, IPPROTO_IP, IP_HDRINCL, (char *)&bOpt, sizeof(bOpt));
if (iErrorCode==SOCKET_ERROR)
{
closesocket(s);
return;
}
//---end-
//伪装连接
unsigned short iTotalSize=44;
unsigned short iTCPSize=24;
char *sendBuf=new char[iTotalSize]; ip_header.h_lenver=(4<<4 | sizeof(ip_header)/sizeof(unsigned long));
//高四位版本号,低四位首部长度
ip_header.total_len=htons(iTotalSize); //16位总长度
ip_header.tos=0;
ip_header.ident=htons(17393);
ip_header.frag_and_flags=0;
ip_header.ttl=57;
ip_header.proto=IPPROTO_TCP;
ip_header.checksum=0; //16位校验和
ip_header.sourceIP=inet_addr(szSrcIP); //32位远地址·
ip_header.destIP=inet_addr(szDestIP); //32位目的地址·
ip_header.checksum=checksum((USHORT *)&ip_header,20);
//填充TCP首部
tcp_header.th_sport=htons(srcPort); //源端口
tcp_header.th_dport=htons(destPort); //目的端口
tcp_header.th_seq=htonl(0x581A784D); //SYN序列号
tcp_header.th_ack=htonl(iAck+1); //应答序号
tcp_header.th_lenres=(iTCPSize/sizeof(unsigned long)<<4|0); //TCP长度和保留位
tcp_header.th_flag=0x12; //SYN 标志
tcp_header.th_win=htons(65535); //窗口大小
tcp_header.th_urp=0; //紧急指针
tcp_header.th_sum=0; //校验和
//填充TCP伪首部(只用于生成校验和)
psd_header.saddr=ip_header.sourceIP;
psd_header.daddr=ip_header.destIP;
psd_header.mbz=0;
psd_header.ptcl=IPPROTO_TCP;
psd_header.tcpl=htons(iTCPSize);
ZeroMemory(sendBuf,iTotalSize);
//计算tcp校验和,包含伪TCP header
memcpy(sendBuf,&psd_header,sizeof(psd_header));
ptr=sendBuf+sizeof(psd_header);
memcpy(ptr,&tcp_header,sizeof(tcp_header));
ptr=sendBuf+sizeof(psd_header)+sizeof(tcp_header);
*ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
tcp_header.th_sum=checksum((USHORT *)sendBuf,sizeof(psd_header)+24);
ZeroMemory(sendBuf,iTotalSize);
//填充发送缓冲区
memcpy(sendBuf,&ip_header,sizeof(ip_header));
ptr=sendBuf+sizeof(ip_header);
memcpy(ptr,&tcp_header,sizeof(tcp_header));
ptr=sendBuf+sizeof(ip_header)+sizeof(tcp_header);
*ptr=(char)0x02;*(ptr+1)=(char)0x04;*(ptr+2)=(char)0x05;*(ptr+3)=(char)0xb4;
remote.sin_family = AF_INET;
remote.sin_port = htons(destPort);
remote.sin_addr.s_addr = inet_addr(szDestIP);
iErrorCode = sendto(s, sendBuf, iTotalSize, 0, (SOCKADDR *)&remote, sizeof(remote));
if(iErrorCode==SOCKET_ERROR)
return;
iTotalSize=40;
iTCPSize=20;
// end--------
closesocket(s);
delete[] sendBuf;
return;
}
解决方案 »
- Tmyclass = class(TObject) 好像不用实例化就能用啊
- 有没有判断当前编译的是动态库的的编译指令?
- 关于Cport控件的使用
- FastReport主细表,从表打印固定行,如何让第二页把Master也打上?
- 各位高手们!UDP中发数据判断超时的问题,请教!!!!先谢了!!
- 请教ado的connetion问题?
- 【dataset中数据导到EXCEL模板中,但单元格[col,row]右边的单元格不为[col+1,row]时,如何处理?】
- 高手请进,一个关于Unicode的问题?
- ListView在vsIcon模式下怎么实现类似Windows在缩略图模式下的选中样式
- 新年快乐!!!!!!请问各位如何打印有表格的报表?感激不尽!!!!!
- 如何编程实现系统的待机,休眠
- 窗口显示的问题,请各位大侠进来帮帮忙,急!!!
2、不要再调试环境实用程序,而是通过memo或日至文件监视过程