如题 控件用的是TSERVERSOCKET 和 TCLIENTSOCKET  刚开始直接传输字符串可以实现 后面改成传输消息包 要获取和传递包头信息就有点搞不来了 弄了一天没效果 希望高手帮忙写段代码或者给个样例 小弟感激不尽 http://blog.csdn.net/lengfeng847/archive/2010/08/20/5827141.aspx  内容在上面的连接博客 帮忙看下 谢谢!

解决方案 »

  1.   

    網上很多類似實例,你參考下這一個貼子:http://hcqi2004.blog.163.com/blog/static/72682418200925112641385/
      

  2.   

    谢谢lz
    近有个项目用到delphi 以前学过 但是网络通讯这块不懂 以前是直接接受字符串现在改用传递信息包 希望大侠帮忙写下接受和发送特定信息包的代码下面为信息包的格式和内容数据包格式如下图所示,所包含的内容从左到右进行传输:包头中的信息全部为网络字节顺序!
    序号
     字段名称
     长度(Bytes)
     类型(C++)
     字段说明
     
    1
     head
     2
     Unsigned Short
     包头标识,固定为0xFFFF
     
    2
     version
     2
     Unsigned Short
     版本信息,当前为0x0030
     
    3
     length
     2
     Unsigned Short
     包括包头的全部包体长度
     
    4
     command
     2
     Unsigned Short
     命令号
     
    5
     status
     4
     Unsigned Integer
     应答状态
     
    6
     taskid
     4
     Unsigned Integer
     任务流水号
     
    7
     sender
     4
     Unsigned Integer
     发送方标识1
     
    8
     sessionid
     4
     Unsigned Integer
     发送方标识2
     
    9
     timestamp
     4
     Unsigned Integer
     时间戳
     
    10
     flag
     2
     Unsigned Short
     数据加密标志:0:不加密,1:DES加密
     
    11
     reserved
     4
     Unsigned Integer
     保留字段
     
    包头信息中,开始标识(head),版本信息(version)为固定格式;包体长度(length),提示整个包体(包括包头)的长度,接收方据此来完成一个业务数据包的接收和解析;命令号(command),为客户端和服务器约定的业务命令,从0到65535,具体定义详见下表:号码段   
     起始编号
     结束编号
     使用说明
     
    1
     0X0000
     0X03E7
     对应具体的业务命令号,如1为充值等
     
    2
     0X03E8
     0XFFFF
     系统保留命令字,目前0XFFFE为心跳包,0XFFFF为心跳应答包
      应答状态(status),请求时总设置为0;应答时,由SP应用服务程序返回相应的操作结果或错误原因;任务流水号(taskid)由自行定义,SP应用程序在响应包中必须返回,SP应用程序可以将此作为数据包一段时间内的唯一序列号。发送方标识1(sender)、发送方标识2(sessionid)、时间戳(timestamp)以及保留字段(reserved),可以为发送方保留一些私有信息,返回包时原样返回。包头信息中,除了包体长度(length)以外,其他的字段,包括开始标识(head),版本信息(version),任务流水号(taskid),发送方标识1(sender),发送方标识2(sessionid),时间戳(timestamp),以及数据加密标识(flag),需要在响应包中原样返回;
    流程
    1、                   通用网关在连接建立之后,根据刚才加密的字节流,加上信息包头,组合成信息包,然后发送(Send)信息包,发送的字节数为加密后的字节流字节数+24(24信息包头的字节长度);在上述的例子中,信息包大约如ffff0200 00001100 00004e5f 00114b3f 00000000 0100 0038 2fd65329e2770074791503c2dab1d209fe0225636dd07f7277bd291209e1a498df28f7af2f0eb4f1be2831f0fa8987b7f9;其中业务加密字节流的长度这里是56,体现在网络字节中是0x0038,如果是x86系列的PC,需要做主机到网络(ntohs)字节顺序转换;2、                   SP应用服务程序接收(Recv)该信息包,根据包头信息截取对应的字节流,然后进行解密处理,得到加密前的业务字符串,另外还需要把其他的包头标识、两个包头保留字,存储在本地;3、          SP应用服务程序根据流程开发人员与之协商好的格式对接收的字符串进行解析,然后进行响应的处理4、     SP应用服务程序在发送之前,同样根据密匙对该返回字符串进行加密处理,然后对加密字节流长度进行计算,加上刚才发送过来的包头标识和版本号以及保留字等,组合成信息包;注意这时,字节流的长度是返回加密字节流的长度,而且是网络字节的以下是自己接受字符串的时的代码
    procedure TForm1.ServerSocketClientRead(Sender: TObject;
      Socket: TCustomWinSocket);
    var
      lmsg:String;
      vflag,i,j:Integer;
      larriveDate:TarriveDate;
      ip:String;
      islimit:Boolean;
      resData:String;//返回数据
      buff:array[0..255]of  byte;
    begin
     ip:=Socket.RemoteAddress;
     islimit:=True;
     For j:=0 to ips.Count-1 Do
     Begin
       if (ip=ips[j]) then
       begin
        islimit:=False;
       end;
     End;
     if not islimit then
     Begin
     CoInitialize(nil);
     Socket.ReceiveBuf(buff,4);//应该就在这里修改吧
     lmsg:=Socket.ReceiveText;
     SendTo();
     Memo1.Lines.Add(DateTimeTostr(now)+'来自主机'+ip+'的请求数据:'+lmsg );
     saveToLog(DateTimeTostr(now)+'来自主机 '+ip+ ' 的请求数据:'+ lmsg);
     if lmsg<>'' then
     Begin
     try
     saveToLog(DateTimeTostr(now)+'开始处理接受数据'+lmsg);
     larriveDate:=analyecmdData(lmsg);
     vflag:=exChange(larriveDate);
     Memo1.Lines.Add('*'+Socket.ReceiveText+'*'+lmsg);
     Memo1.Lines.Add(DateTimeTostr(now)+'数据处理完毕:处理结果:'+inttostr(vflag));
     saveToLog(DateTimeTostr(now)+'数据处理完毕:处理结果:'+inttostr(vflag)); except
      begin
       vflag:=1;
       Memo1.Lines.Add(DateTimeTostr(now)+'数据处理异常:'+inttostr(vflag));
       saveToLog(DateTimeTostr(now)+'数据处理异常:'+inttostr(vflag));
      end;
      //vflag:=1;
     end;
      for i:=0 to sessions do
        begin //取得匹配的客户端
          if session[i].CHandle = Socket.SocketHandle then
          begin
            case  vflag of
              0:  resData:=inttostr(vflag)+'$'+larriveDate.userID+'$'+larriveDate.TelNo+'$'+inttostr(larriveDate.inPutKey);
              1:  resData:='1'+'$'+'系统繁忙请稍后冲值';
              2:  resData:='2'+'$'+'平台用户ID不存在';
            end;        session[i].CSocket.SendText(resData);
            Memo1.Lines.Add(DatetimeTostr(now)+'向客户端发送处理完毕命令'+resData);
            saveToLog(DatetimeTostr(now)+'向客户端发送处理完毕命令'+resData);
          end;
        end;
     end;
     CoUninitialize;
     end
     else
     Begin
     CoInitialize(nil);
     CoUninitialize;
     // saveToLog(DatetimeTostr(now)+'非法访问Ip'+ip+'访问被阻止');
     End;
    end;
    2个问题
    1现在不会写的代码是如何获得信息包然后再按包头格式分析出包头和数据信息
    2把处理后的数据加上以前的报头信息一起做应答处理
    哪位帮忙看下 我把工程发你帮我完善下那部分代码 谢谢 我QQ419718285 你给个联系方式我联系你行