客户端发送的代码:
var
  StreamLen : Integer;
  XMLArray  : Array Of Byte;
begin
  StreamLen := 333;
  SetLength(XMLArray, 12); 
  
  XMLArray[0] := StreamLen;
  XMLArray[1] := StreamLen shr 8;
  XMLArray[2] := StreamLen shr 16;
  XMLArray[3] := StreamLen shr 24;  XMLArray[8 + 0] := 1;
  XMLArray[8 + 1] := 1 shr 8;
  XMLArray[8 + 2] := 1 shr 16;
  XMLArray[8 + 3] := 1 shr 24;  mySocket := TTCPClient.Create(nil);
  mySocket.RemotePort := '8000';
  mySocket.RemoteHost := '127.0.0.1';
  mySocket.BlockMode := bmNonBlocking;
  mySocket.Active := True;
  mySocket.SendBuf(XMLArray, 12);
end;
调试状态下看到XMLArray为{77,1,0,0,0,0,0,1,0,0,0,0}服务器端接收代码:
socket = new ServerSocket(port);
while (!isClose)
{
      try
      {
        client = socket.accept();
        if (client!=null){
           new Client(client);          <----进入处理线程
        }  
      }catch(Exception ex){}
}<- 处理线程 ->
byte[] head = new byte[12];
try{
    //设置3分钟超时
    socket.setSoTimeout(180000);    DataInputStream in = new DataInputStream(socket.getInputStream());
    while (isRun)
    {
      int length = 0;
      try{
        length = in.read(head, 0, 12);
      }catch(SocketTimeoutException ex){
        break;
      }catch(SocketException ex){
        break;
      }     if (length!= 12)              <--- length确实等于12,      
     {                             <--- 但head的值为{76,47,-48,0,12,42,-48,0,24,55,-48,0}
       break;
     }
   }
}catch(Exception ex){}
请问是什么原因倒致接收到的数据与发送数据不一符呢?

解决方案 »

  1.   

    你的服务器接收到的字节肯定是4个字节的字符串,而且是物理地址信息,一般显示乱码
    解决办法不能定义成XMLArray  : Array Of Byte;
    应该定义成:XMLArray  : Array[0..11] Of Byte;
      

  2.   

    SendBuf的动作是发送一组字符串数组,非连续的字符串,
    你定义成XMLArray  : Array Of Byte;
    系统只是动态分配物理地址空间给变量XMLArray。XMLArray是相对内存物理地址一个指针。
    你用sendtext动作可以这样做
      

  3.   

    但是我上面的代码只是一个包的包头(其中包含整个包的长度,包头定长是12),其实情况Byte数组的长度是不定长的。那我应该如何去申明这个Byte数组?
      

  4.   

    我明白你的意思,在用tcp/ip协议发送结构体的字符串是必须定义成一个字符数组。
    Byte数组要看最长可能会多长,你就定义多长,这一点是没办法的。
    这个跟移动根联通的短信网关协议基本上是一致的。
    我不知道你的程序是做什么用的
      

  5.   

    我的程序是做内部通讯用的。其中,服务器端是早就已经建立好的。内部通讯以XML数据包为基本格式,然后加上包的长度做包头,以符合TCP/IP协议传递的要求。现在用Delphi做的这个客户端是新加的。请问现在这种情况如何解决呢?
      

  6.   

    我看你的服务器端定义的head = new byte[12];不也是定长的吗?
    我想知道
    服务器端,数据接收,变量你是怎样定义的?
      

  7.   

    我刚才说了,包头是定长的,所以获取包头的时候,自然知道长度。接下来的包体长度就由包头中的存储长度来设定。
    //先取包头,将包头的变量转换成整型长度
    int size = Tools.byteToInt(head);
    byte[] body = new byte[size];try{
       length = in.read(body, 0, size);
    }catch(SocketTimeoutException ex){
      Logs.println("读取数据超时!服务器自动关闭连接[" + socket.getLocalPort() + "]!!");
      break;
    }catch(SocketException ex){
      break;
    }if (length!= size)
    {
         break;
    }
    Logs.println("[" + tt.getName() + "]收到从 " +
                           socket.getRemoteSocketAddress().toString() +
                           " 发来的报文:\n" + Tools.byteArrayToString(body));
       try
       {
         //ShortMessage 是自定义的XML类,构造一个XML包
         msg = new XMLMessage(body);                   //通过接口转换到另一个线程去处理
         msgRecvIf.Recv(socket, msg); 
        }catch (Exception ex){
                Logs.printError(ex,"监听端口XML数据失败:" + Tools.byteArrayToString(body));
                SocketClient.sendReportMsg(socket,null,"-999",null);
                break;
        }
      

  8.   

    to  huiwww(十足菜鸟):我有点不明白,直接定义一个定长数组与定义一个动态数组有什么区分吗?我只知道动态数组定义的时候是没有分配内存空间的。那么在SetLength的时候,分配的空间是不连续的吗?
      

  9.   

    呵呵,数据发送接收一致性方面已经解决了。因为动态数组实际上是一个指针数组,所以在发送的时候改一下就可以了。mySocket.SendBuf(XMLArray, 12);改成mySocket.SendBuf(XMLArray[0], 12);
      

  10.   

    更奇怪的是我把TTcpclient.BlockMode设置成nonblock以后,连server
    都无法连接上了,我不知道老兄你这样写是连接上去了?有人说ttcpclient有问题,不知道大家在需要nonblock mode的时候都用什么控件