前人用delphi编的服务器用来和VC编的客户端通信,有些不合理的地方,老板让我这个没接触过Delphi的新手修改,有些程序看不通望大牛指导:按文档说明应当是:
服务器与客户端通信时:
服务器端确认后返回值4E4E
客户端每发送1包,等待服务器返回确认。
如果返回0x0E0E,表示数据传送正确,继续下一包;
如果返回0x4545,表示数据传送错误,重新发送这一包。类似以上的关键字,但是我从该句并没有看出相关的东西,后面的一句ClientSocket.SendText('E');这个倒是符合要求 E的ASCII即16进制的45相关语句如下:Begin
  While Not Terminated And ClientSocket.Connected Do
  begin
    Try
      //如果没有接受数据,延时10秒后中断连接线程
      SocketStream := TWinSocketStream.Create(ClientSocket, 10000);
      Try
        if Not RecvingClient then
        begin
          FillChar(FirstData, SizeOf(FirstData), 0);
          If SocketStream.Read(FirstData,8) = 0 Then
          Begin
            ClientSocket.SendText('Timeout on Server'+#13#10);//这句向socket发送的是什么?
            sleep(1);
            ClientSocket.Close;
            Terminate;
          End;
          CBufRecv:=FirstData;
          
          if JudgeCustomer(CBufRecv) then
          begin
            ClientSocket.SendBuf(CBufRecv^,2);
            //列为已注册用户
       InsertClientToTre(ClientSocket.RemoteAddress,FrmMain.TreeView1.Items[0]);
          end
          else
          begin
            //列为未知用户
       InsertClientToTre(ClientSocket.RemoteAddress,FrmMain.TreeView1.Items[1]);            ClientSocket.SendText(Copy(String(FirstData),0,2));//该句发送的是?            CBufRecv^:=char(5);
             end;

解决方案 »

  1.   

    unit UntClient;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls, Buttons, ExtCtrls,WinSock;type
      TFileInfo=packed record
      FileName:array[0..1024-1] of char;
      FileSize:integer;
    end;
    type
      TFrmClient = class(TForm)
        Panel1: TPanel;
        Memo1: TMemo;
        Panel2: TPanel;
        BitBtn1: TBitBtn;
        BitBtn2: TBitBtn;
        BitBtn3: TBitBtn;
        BitBtn4: TBitBtn;
        procedure BitBtn3Click(Sender: TObject);
        procedure BitBtn1Click(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      FrmClient: TFrmClient;implementation{$R *.dfm}procedure TFrmClient.BitBtn3Click(Sender: TObject);
    begin
      close;
    end;procedure TFrmClient.BitBtn1Click(Sender: TObject);
    var
      c:TSocket;
      SAddr:TSockAddr;
      WSA:TWSAdata;
      WSAStatus,len:integer;
      FileInfo:TFileInfo;
    begin
      try
      WSAStatus:=WSAStartUP($202,WSA);
      if WSAStatus<>0 then
      begin
        Memo1.Lines.Add('WSAStatus Error');
        Exit;
      end;   c:=Socket(AF_INET,SOCK_STREAM,0);
       if c<0 then
       begin
         Memo1.Lines.Add('Socket Failed');
         exit;
       end;
      SAddr.sin_family:=AF_INET;
      SAddr.sin_port:=htons(2007);
      SAddr.sin_addr.S_addr:=inet_addr('127.0.0.1');
      len:=SizeOf(TSockAddr);
      WSAStatus:=connect(c,SAddr,len);  if WSAStatus<>0 then
      begin
        Memo1.Lines.Add('Connect to Error');
        exit
      end;
      Recv(C,FileInfo,SizeOf(TFileInfo),0);
      Memo1.Lines.Add('FileName='+FileInfo.FileName+#13#10+'Length='+IntToStr(FileInfo.FileSize));
      closesocket(c);
      finally
        Memo1.Lines.Add('Thread end');
        WSACleanUP();
      end;
    end;end.
      

  2.   

    你可以参考一下
    下面是服务端监听线程 和工作线程
    unit UntWorkThread;interfaceuses
      Classes,Winsock,StdCtrls,SysUtils,ComCtrls,idGlobal;type TFileInfo=packed record
      FileName:array[0..1024-1] of char;
      FileSize:integer;
    end;type
      TWorkThread = class(TThread)  private
        FSocket:TSocket;
        { Private declarations }
      protected
        procedure Execute; override;
        procedure SendFile;
      public    Console:TMemo;
        fn:String;
        ProgBar:TProgressBar;
        property C:TSocket write FSocket;
        procedure Disconnect;
      end;
    var
      WorkThread:array [0..10] of TWorkThread;
    implementation{ Important: Methods and properties of objects in VCL or CLX can only be used
      in a method called using Synchronize, for example,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure TWorkThread.UpdateCaption;
        begin
          Form1.Caption := 'Updated in a thread';
        end; }{ TWorkThread }//------------------------------------------------------------------------------
    procedure TWorkThread.Execute;
    begin  Synchronize(SendFile);
      { Place thread code here }
    end;
    //------------------------------------------------------------------------------
    procedure TWorkThread.SendFile;
    const BUFSIZE:integer=1024*2;
    var
      FHandle,Length:integer;
      SendBuf:array [0..49] of char;
      FileInfo:TFileInfo;
    begin
      if Not FileExists(fn) then exit;
      FHandle:=FileOpen(fn,fmOpenRead or fmShareDenyNone);
      if FHandle<=0 then
      begin
        Console.Lines.Add('打开文件失败!线程结束');
        Disconnect;
        exit;
      end;
      StrCopy(FileInfo.FileName,Pchar(ExtractFileName(fn)));
      FileInfo.FileSize:=FileSizeByName(fn);
      if FSocket=INVALID_SOCKET then
      begin
        Console.Lines.Add('INVALID_SOCKET'+IntToStr(FSocket));
      end;
      Length:=Send(FSocket,FileInfo,SizeOf(TFileInfo),0);
      Console.Lines.Add('Send length '+InttoStr(Length));
     { While not Terminated do
      begin
         Send(FSocket,);  end; }
      disconnect;
      FileClose(FHandle);
    end;
    //------------------------------------------------------------------------------
    procedure TWorkThread.Disconnect;
    begin
      closesocket(FSocket);end;
    end.
    工作线程:
    unit UntSend;interfaceuses
      Classes,Winsock,StdCtrls,SysUtils,ComCtrls,UntWorkThread;type
      TListenThread = class(TThread)
      private
        S,C:TSocket;
        SAddr,CAddr:TSockAddr;
        WSA:TWSAdata;
        WSAStatus:Integer;    { Private declarations }
      protected
        procedure Execute; override;
        procedure StartListen;
      public
        Console:TMemo;
        fn:String;
        ProgBar:TProgressBar;
        procedure StopListen;  end;implementation{ Important: Methods and properties of objects in VCL or CLX can only be used
      in a method called using Synchronize, for example,      Synchronize(UpdateCaption);  and UpdateCaption could look like,    procedure SendFile.UpdateCaption;
        begin
          Form1.Caption := 'Updated in a thread';
        end; }{ SendFile }const PORT:Integer=2007;
    //------------------------------------------------------------------------------
    procedure TListenThread.Execute;
    begin
      { Place thread code here }
       startListen;
       Console.Lines.Add('The Thread Stop !');
    end;
    //------------------------------------------------------------------------------
    procedure TListenThread.StartListen;
    var
      i:integer;
    begin
      try
       WSAStatus:= WSAStartUp($202,WSA);
       if WSAStatus<>0 then
       begin
         Console.Lines.Add('WSAStartUp Failed !');
         exit;
       end;
       Console.Lines.Add('WSAStartUp Successful!');   s:=Socket(AF_INET,SOCK_STREAM,0);
       if s<0 then
       begin
         Console.Lines.Add('Socket Failed');
         exit;
       end;
       Console.Lines.Add('Socket OK!');   SAddr.sin_family:=AF_INET;
       SAddr.sin_port:=htons(PORT);
       SAddr.sin_addr.S_addr:=INADDR_ANY;   WSAStatus:=bind(s,SAddr,sizeof(SAddr));
       if WSAStatus<>0 then
       begin
         Console.Lines.Add('Bind Failed1');
         exit;
       end;
       Console.Lines.Add('Bind OK!');   WSAStatus:=listen(s,5);
       if WSAStatus<>0 then
       begin
         Console.Lines.Add('Listen Failed');
         exit;
       end;
       Console.Lines.Add('Listen OK'+#10+'Server Port'+inttostr(PORT));   WSAStatus:=Sizeof(CAddr);   i:=0;
       c:=accept(s,@CAddr,@WSAStatus);
       Console.Lines.Add('A Client connected');   while true do
       begin
          WorkThread[i]:=TWorkThread.Create(true);
          WorkThread[i].FreeOnTerminate:=true;
          WorkThread[i].Console:=Console;
          WorkThread[i].fn:=fn;
          WorkThread[i].ProgBar:=ProgBar;
          WorkThread[i].c:=c;
          WorkThread[i].Resume;
          if s=INVALID_SOCKET then break;
          c:=accept(s,@CAddr,@WSAStatus);
          sleep(10);
          inc(i);
       end;
       Console.Lines.Add('The ListenSock Closed!');
      finally
        Console.Lines.Add('Clean WSADAtA');
        WSACleanUP();
      end;
    end;
    //------------------------------------------------------------------------------
    procedure TListenThread.StopListen;
    begin
      closesocket(s);end;
    end.