CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  网络通信/分布式开发

为什么我用RawSocket自定义IP包却总是发送不出去?

楼主wanglin1983125(汪汪)2005-06-04 18:44:25 在 Delphi / 网络通信/分布式开发 提问

我想往局域网内的另一台电脑发送一个自定义的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;  
  }  
   
  问题点数:0、回复次数:7Top

1 楼lovend(颓废之吻)回复于 2005-06-04 19:04:06 得分 0

帮你顶Top

2 楼qinmaofan(采菊南山下【抵制日货】)回复于 2005-06-06 15:27:02 得分 0

请调试看是到哪里出的错,并用   wsagetlasterror   查看错误代码。Top

3 楼xukaiming(许开明)回复于 2005-06-06 16:33:32 得分 0

mark  
  Top

4 楼chwdong(chwdong)回复于 2005-06-06 21:39:40 得分 0

1、每次发送要加延时,防止对方没有处理,导致丢包  
  2、不要再调试环境实用程序,而是通过memo或日至文件监视过程Top

5 楼lovend(颓废之吻)回复于 2005-06-07 00:37:44 得分 0

帮你顶Top

6 楼heluqing(鉴之小河〖劳累求充实〗)(vcl .net)回复于 2005-06-07 13:36:28 得分 0

关注,最近也在搞这个...Top

7 楼heluqing(鉴之小河〖劳累求充实〗)(vcl .net)回复于 2005-06-09 16:24:01 得分 0

upup...Top

相关问题

  • 关于自定义IP
  • 如何实现发送一个IP包和接收一个IP包,包是自定义的
  • 包含‘自定义控件’的‘自定义复合控件’中‘自定义控件’状态保持问题?
  • 请问VB可以自定义IP报头吗?
  • 自定义公共类的装载,包的定义
  • 自定义的结构中可以包含内对象吗?
  • 关于自定义包的问题?请高手指教。
  • installShield程序打包问题---自定义组件出错.
  • 关于自定义包的问题,求救~~~~~~~~~~~~~~~
  • 发送自定义ARP包。请cyAnalyst(cc)进入

关键词

  • tcp
  • socket
  • ip
  • delphi
  • word
  • itotalsize
  • header
  • itcpsize
  • bopt
  • iack

得分解答快速导航

  • 帖主:wanglin1983125

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo