程序的大致结构是这样的,我用socket实现多个客户端同时向服务端传送文件,我知道程序设计思想是每当一个客户端与服务端连接时,服务端就建立一个线程与服务端连接,我现在不知道如何用代码来实现每当一个客户端与服务端连接时,服务端就建立一个线程与服务端连接,并实现文件传输.如果哪位能给出一段源码,我将不胜感激.

解决方案 »

  1.   

    服务器端的ServerSockt是根据客户请求自动增加和减少连接的,对于每个客户端,都可以认为服务器端只为它单独服务。没有必要额外进行多线程编程。
      

  2.   

    建立一个线程与客户端作传输很简单,在OnGetThread事件写就是了
    type
      TClientThread = class(TServerClientThread)
      protected
        procedure ClientExecute; override;
      end;procedure TClientThread.ClientExecute;
    begin
      我接,我接接接
    end;procedure TForm1.ServerSocket1GetThread(Sender: TObject;
      ClientSocket: TServerClientWinSocket;
      var SocketThread: TServerClientThread);
    begin
      SocketThread := TClientThread.Create(False, ClientSocket);
    end;客户端就用一个线程中使用ClientSocket去连接服务端。然后发数据。难点:
    自定义传输过程中数据发送接收的协议。嘿嘿,我也实现的不是很好。
      

  3.   

    copy_paste(木石三):
    那客户端怎么用多线程呢?
    你一定要告诉我,因为如果不用多线程的话,在发送数据的时候,就很难操作客户端界面了
      

  4.   

    type
      TSendThread = class(TThread)
      private
        FFileName: string;
        FSocket: TCustomWinSocket;
        function Send(var Buffer; Count: Integer): Integer;
      protected
        procedure Execute; override;
      public
        constructor Create(ASocket: TCustomWinSocket; AFileName: string);
      end;//发送完数据后,由服务端返回接收的字节数。看看是否正确,正确则继续读文件内容再发
    function TSendThread.Send(var Buffer; Count: Integer): Integer;
    var
      FDSet: TFDSet;
      TimeVal: TTimeVal;
      RetVal: Integer;
    begin
      if FSocket.SocketHandle <> INVALID_SOCKET then
      begin
        Result := FSocket.SendBuf(Buffer, Count);
        if Result <> Count then
          raise ESocketError.Create('Socket send error.');
        Result := -1;
        FD_ZERO(FDSet);
        FD_SET(FSocket.SocketHandle, FDSet);
        TimeVal.tv_sec := 10;
        TimeVal.tv_usec := 0;
        RetVal := select(0, @FDSet, nil, nil, @TimeVal);
        if RetVal > 0 then
        begin
          RetVal := FSocket.ReceiveBuf(Result, SizeOf(Result));
          if RetVal <> SizeOf(Result) then
            raise ESocketError.Create('Socket read error.');
        end;
      end
      else
        raise ESocketError.Create('Socket invalid');
    end;procedure TForm1.ThreadTerminate(Sender: TObject);
    begin
      FThread := nil;
    end;//中止传输
    procedure TForm1.Button2Click(Sender: TObject);
    begin
      if Assigned(FThread) then
        FThread.Terminate;
    end;//开始传
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      if not Assigned(FThread) then
      begin
        ClientSocket1.Close;
        Sleep(10);
        ClientSocket1.Host := HostEdit.Text;
        ClientSocket1.ClientType := ctBlocking;
        ClientSocket1.Open;
        if not FileExists(FileEdit.Text) then
          raise Exception.CreateFmt('File: %s not exists', [FileEdit.Text]);
        FThread := TSendThread.Create(ClientSocket1.Socket, FileEdit.Text);
        FThread.OnTerminate := ThreadTerminate;
      end;
    end;代码只能给到这份了,我也没调完,很多错,还down机,代码发送代码接收代码再说吧
      

  5.   

    我只是不能随便把公司的源代码拿出来分享,要不早就把控件源代码拿出来了。(服务器端和客户端各一个,传输进度显示,随时终止,多用户,传输尺寸为几百兆的单个文件没有任何问题,多个文件传输也是再流畅不过了,可以说不亚于多个计算机从或向同一个计算机的共享目录拷贝文件)。至于技术细节,就是我上面介绍的,确实根本不不用多线程。俺们的服务器是NT 4 Server,客户端随便,经验证明用 Windows 98 SE 传输速率最快。实际上,你可以看看Delphi6中Indy组件的源代码,那些都是精华。(俺们的传输组件是在Delphi5的时候写的,如果那时有Delphi6,就几乎不用写了。)俺们都尽量不用Socket了。可以不幸地告诉楼主,俺们最初也是用多线程写的,可是效率实在不敢恭维(也许是俺们机器配置太低吧),因此才仔细研究 MS SDK 中有关 Socket 的说明,终于搞掂。
      

  6.   

    楼主,美死你(俺刚想到的,俺曾经发表过与此有关的文章来着):
    http://tech.163.com/tm/010607/010607_22708.html
    现在俺不替你着急了。当初俺也是这么过来的。
      

  7.   

    我知道用流的形式传送,
    我现在问的是如何使用socket多线程,
    如果分不够的话我还可以再加