最近想做一个TCP通讯的东西,在网上找了下面这段代码(Delphi7+indy10),改了一些,发现问题好多 
主要是server回复,就报错,客户端接收的代码屏蔽,只是报错,不屏蔽就挡机了 
请高手帮我看看,十分感谢! 
unit Unit1;interfaceuses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
  IdComponent, IdTCPServer, IdContext, IdGlobal;type
  TForm1 = class(TForm)
    mmo1: TMemo;
    mmo2: TMemo;
    idtcpsrvr1: TIdTCPServer;
    idtcpclnt1: TIdTCPClient;
    btn1: TButton;
    btn2: TButton;
    btn3: TButton;
    btn4: TButton;
    procedure FormCreate(Sender: TObject);
    procedure btn2Click(Sender: TObject);
    procedure idtcpclnt1Connected(Sender: TObject);
    procedure idtcpsrvr1Connect(AContext: TIdContext);
    procedure idtcpsrvr1Execute(AContext: TIdContext);
    procedure btn4Click(Sender: TObject);
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;  sttBuffer = record
    id: Integer;
    word: array [0..11] of char;
  end;var
  Form1: TForm1;
  PacketID: integer;
  
const
  RSMTimer: LongWord = 300;procedure ReadSrvMsg;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
begin
  idtcpsrvr1.DefaultPort:=540;
  idtcpsrvr1.Active:=True;
  mmo1.Lines.Add('侦听540成功.');
end;procedure TForm1.btn2Click(Sender: TObject);
begin
  try
    mmo2.Lines.Add('正在试图连接服务器');
    idtcpclnt1.Host:='localhost';
    idtcpclnt1.Port:=540;
    idtcpclnt1.Connect;
    btn2.Enabled:=false;
  except
    mmo2.Lines.Add('连接失败');
  end;
end;procedure TForm1.idtcpclnt1Connected(Sender: TObject);
begin
  mmo2.Lines.Add('服务器已连接上.');
  SetTimer(Handle, RSMTimer, 20, @ReadSrvMsg);
end;procedure TForm1.idtcpsrvr1Connect(AContext: TIdContext);
begin
  mmo1.Lines.Add('客户端已连接上');
end;procedure TForm1.idtcpsrvr1Execute(AContext: TIdContext);
var
  Buffer: sttBuffer;
  tmpBuffer: TIdBytes;
begin
  //Bytes方式接收结构
  AContext.Connection.Socket.ReadBytes(tmpBuffer,SizeOf(sttBuffer),false);
  BytesToRaw(tmpBuffer,Buffer,SizeOf(sttBuffer));     //此处用CopyMemory和Move均有问题,百思不得其解,不知道是不是对齐的原因
  mmo1.Lines.Add('接收:'+inttostr(Buffer.id)+','+Buffer.word);  //回包
  StrPCopy(Buffer.word,'我收到了');
  tmpBuffer:=@Buffer;
  AContext.Connection.IOHandler.Write(tmpBuffer);
end;procedure TForm1.btn4Click(Sender: TObject);
var
  Buffer: sttBuffer;
  sndBuffer: TIdBytes;
begin
  sndBuffer:=@Buffer;
  SetLength(sndBuffer,SizeOf(sttBuffer));
  idtcpclnt1.Socket.Write(sndBuffer);end;procedure TForm1.btn1Click(Sender: TObject);
begin
  idtcpsrvr1.Active:=false;
end;
procedure ReadSrvMsg;
var
  Buffer: sttBuffer;
  tmpBuffer: TIdBytes;
begin
  //回复的结构
  Form1.idtcpclnt1.Socket.ReadBytes(tmpBuffer,SizeOf(sttBuffer),false);
  BytesToRaw(tmpBuffer,Buffer,SizeOf(sttBuffer));
  Form1.mmo1.Lines.Add('返回:'+inttostr(Buffer.id)+','+Buffer.word);
end;end.

解决方案 »

  1.   

      //回包
      StrPCopy(Buffer.word,'我收到了');
      tmpBuffer:=@Buffer;改为:  //回包
      StrPCopy(Buffer.word,'我收到了');
      tmpBuffer:=RawToBytes(Buffer, SizeOf(sttBuffer));
      

  2.   

    procedure TForm1.btn4Click(Sender: TObject);
    var
      Buffer: sttBuffer;
      sndBuffer: TIdBytes;
    begin
      sndBuffer:=@Buffer;
      SetLength(sndBuffer,SizeOf(sttBuffer));
      idtcpclnt1.Socket.Write(sndBuffer);end;改为:
    procedure TForm1.btn4Click(Sender: TObject);
    var
      Buffer: sttBuffer;
      sndBuffer: TIdBytes;
    begin
      //sndBuffer:=@Buffer;
      //SetLength(sndBuffer,SizeOf(sttBuffer));
      sndBuffer := RawToBytes(Buffer, SizeOf(sttBuffer));
      idtcpclnt1.Socket.Write(sndBuffer);end;
      

  3.   

    十分感谢,此问题已解决.
    不过client在读取server返回的数据时,开了一个线程不停读取,以下是代码,希望对后来者有用unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, IdTCPConnection, IdTCPClient, IdBaseComponent,
      IdComponent, IdTCPServer, IdContext, IdGlobal;type
      TForm1 = class(TForm)
        mmo1: TMemo;
        mmo2: TMemo;
        idtcpsrvr1: TIdTCPServer;
        idtcpclnt1: TIdTCPClient;
        btn1: TButton;
        btn2: TButton;
        btn3: TButton;
        btn4: TButton;
        procedure FormCreate(Sender: TObject);
        procedure btn2Click(Sender: TObject);
        procedure idtcpclnt1Connected(Sender: TObject);
        procedure idtcpsrvr1Connect(AContext: TIdContext);
        procedure idtcpsrvr1Execute(AContext: TIdContext);
        procedure btn4Click(Sender: TObject);
        procedure btn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;  FRcvRetBuffer = class(TThread)
      protected
        procedure Execute; override;
      end;  sttBuffer = record
        id: Integer;
        word: array [0..11] of char;
      end;var
      Form1: TForm1;
      PacketID: integer;
      RcvRetBuffer: FRcvRetBuffer;
      
    const
      RSMTimer: LongWord = 300;implementation{$R *.dfm}procedure FRcvRetBuffer.Execute;
    var
      Buffer: sttBuffer;
      tmpBuffer: TIdBytes;
    begin
      while 1=1 do
      begin
        Form1.idtcpclnt1.Socket.ReadBytes(tmpBuffer,SizeOf(sttBuffer),false);
        BytesToRaw(tmpBuffer,Buffer,SizeOf(sttBuffer));
        Form1.mmo2.Lines.Add('返回:'+inttostr(Buffer.id)+','+Buffer.word);
      end;
    end;procedure TForm1.FormCreate(Sender: TObject);
    begin
      idtcpsrvr1.DefaultPort:=540;
      idtcpsrvr1.Active:=True;
      mmo1.Lines.Add('侦听540成功.');
    end;procedure TForm1.btn2Click(Sender: TObject);
    begin
      try
        mmo2.Lines.Add('正在试图连接服务器');
        idtcpclnt1.Host:='localhost';
        idtcpclnt1.Port:=540;
        idtcpclnt1.Connect;
        btn2.Enabled:=false;
      except
        mmo2.Lines.Add('连接失败');
      end;
    end;procedure TForm1.idtcpclnt1Connected(Sender: TObject);
    begin
      mmo2.Lines.Add('服务器已连接上.');
      RcvRetBuffer:=FRcvRetBuffer.Create(False);
    end;procedure TForm1.idtcpsrvr1Connect(AContext: TIdContext);
    begin
      mmo1.Lines.Add('客户端已连接上');
    end;procedure TForm1.idtcpsrvr1Execute(AContext: TIdContext);
    var
      Buffer: sttBuffer;
      tmpBuffer: TIdBytes;
    begin
      //Bytes方式接收结构
      AContext.Connection.Socket.ReadBytes(tmpBuffer,SizeOf(sttBuffer),false);
      BytesToRaw(tmpBuffer,Buffer,SizeOf(sttBuffer));
      mmo1.Lines.Add('接收:'+inttostr(Buffer.id)+','+Buffer.word);  //回包
      StrPCopy(Buffer.word,'我收到了');
      //tmpBuffer:=@Buffer;
      tmpBuffer:=RawToBytes(Buffer,SizeOf(sttBuffer));
      AContext.Connection.IOHandler.Write(tmpBuffer);
    end;procedure TForm1.btn4Click(Sender: TObject);
    var
      Buffer: sttBuffer;
      sndBuffer: TIdBytes;
    begin
      sndBuffer:=RawToBytes(Buffer,SizeOf(sttBuffer));
      SetLength(sndBuffer,SizeOf(sttBuffer));
      idtcpclnt1.Socket.Write(sndBuffer);
    end;procedure TForm1.btn1Click(Sender: TObject);
    begin
      idtcpsrvr1.Active:=false;
    end;end.