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机,代码发送代码接收代码再说吧
我只是不能随便把公司的源代码拿出来分享,要不早就把控件源代码拿出来了。(服务器端和客户端各一个,传输进度显示,随时终止,多用户,传输尺寸为几百兆的单个文件没有任何问题,多个文件传输也是再流畅不过了,可以说不亚于多个计算机从或向同一个计算机的共享目录拷贝文件)。至于技术细节,就是我上面介绍的,确实根本不不用多线程。俺们的服务器是NT 4 Server,客户端随便,经验证明用 Windows 98 SE 传输速率最快。实际上,你可以看看Delphi6中Indy组件的源代码,那些都是精华。(俺们的传输组件是在Delphi5的时候写的,如果那时有Delphi6,就几乎不用写了。)俺们都尽量不用Socket了。可以不幸地告诉楼主,俺们最初也是用多线程写的,可是效率实在不敢恭维(也许是俺们机器配置太低吧),因此才仔细研究 MS SDK 中有关 Socket 的说明,终于搞掂。
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去连接服务端。然后发数据。难点:
自定义传输过程中数据发送接收的协议。嘿嘿,我也实现的不是很好。
那客户端怎么用多线程呢?
你一定要告诉我,因为如果不用多线程的话,在发送数据的时候,就很难操作客户端界面了
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机,代码发送代码接收代码再说吧
http://tech.163.com/tm/010607/010607_22708.html
现在俺不替你着急了。当初俺也是这么过来的。
我现在问的是如何使用socket多线程,
如果分不够的话我还可以再加