给你贴一端:server socket
unit ServerThread;
interface
uses
Classes, scktcomp,ComCtrls,SysUtils,Dialogs;
Type
TServerThread=Class(TServerClientThread)
private
FilesName:TStringS;
FS:Array of TfileStream;
FSLen:Array of Integer;
AllFileLength,FileCurrLength:Integer;
Fileth:integer;
function StringsToString(Str:TStrings):String;
public
constructor Create(CreateSusPend:Boolean;ASock:TServerClientWinSocket;AStr:TStrings;ISFilename:Boolean=false);
destructor destroy;override;
protected
procedure Execute;override;
end;
const
FileNameSep=',';
FileLenSep='|';
implementation
{ TServerThread }
constructor TServerThread.Create(CreateSusPend: Boolean;
ASock: TServerClientWinSocket; AStr: TStrings; ISFilename: Boolean);
var
i:integer;
begin
inherited Create(CreateSusPend,ASock);
FilesName:=TStringlIST.Create;
FilesName.Assign(Astr);
SetLength(FS,FilesName.Count);
SetLength(FSLen,FilesName.Count);
AllFileLength:=0;
for i:=0 to FilesName.Count-1 do
begin
FS
:=TFileStream.Create(FilesName,fmOpenRead or fmShareDenyNone);
FSLen:=FS.Size;
Inc(AllFileLength,FSLen);
end;
end;
destructor TServerThread.destroy;
var
i:integer;
begin
for i:=0 to FilesName.Count-1 do
FreeAndNil(FS);
FreeAndNil(FilesName);
inherited destroy;
end;
procedure TServerThread.Execute;
var
WS:TWinSocketStream;
Bufferointer;
ReadTextchar;
SendText:String;
i:integer;
const
ReadLen=1024;
WriteSize=4*1024;
begin
ReadText:='';
WS:=TWinSocketStream.Create(ClientSocket,6000);
try
while (not Terminated) and (ClientSocket.Connected) do
begin
Buffer:=AllocMem(ReadLen);
if WS.WaitForData(6000) then
begin
WS.Read(Buffer^,ReadLen);
ReadText:=Pchar(Buffer);
end;
if ReadText='AskForFileName' then
begin
SendText:='AskForFileName,'+StringsToString(FilesName);
WS.Write(SendText[1],Length(SendText)+1);
end
else if ReadText='AskForFileLen' then
begin
SendText:='';
for i:=low(FS) to High(FS) do
SendText:=SendText+FileLenSep+InttoStr(FSLen);
Delete(SendText,1,Length(FileLenSep));
SendText:='AskForFileLen|'+SendText;
WS.Write(SendText[1],Length(SendText)+1);
end
else if ReadText='AskForData' Then
begin
if FileCurrLength>=FSLen[Fileth] then
begin
Inc(FileTh);
FileCurrLength:=0;
end;
FreeMem(Buffer);
Buffer:=AllocMem(WriteSize);
inc(FileCurrLength,WS.Write(Buffer^,FS[FileTh].Read(Buffer^,WriteSize)));
end
else if ReadText='FileIsover' then
Terminate;
FreeMem(Buffer);
end;
finally
ClientSocket.Close;
WS.Free;
end;
end;
function TServerThread.StringsToString(Str: TStrings): String;
var
FStr:TStrings;
i:integer;
begin
Result:='';
FStr:=TStringList.Create;
FStr.Assign(Str);
for i:=0 to FStr.Count-1 do
Result:=Result+FilenameSep+FStr;
Delete(Result,1,Length(FileNameSep));
end;
end.
Client:
unit clientThread;
interface
uses
Classes,Scktcomp,sysutils,dialogs;
type
TclientThread = class(TThread)
private
{ Private declarations }
FilesName:TStrings;
FS:Array of TFileStream;
FSlen:Array of Integer;
FileLen,CurrLen:Integer;
Fileth:Integer;
ClientSocket:TClientSocket;
function StringToStrings(Sep,Str:String;Files:Boolean=false):TStrings;
procedure SetString(InText: String);
procedure StartTrans;
procedure Endtrans;
protected
procedure Execute; override;
public
constructor create(CreateSuspend:Boolean;Asocket:TClientSocket);
Destructor Destroy;Override;
end;
implementation
uses ClientUnit;
{ TclientThread }
constructor TclientThread.create(CreateSuspend: Boolean;
Asocket: TClientSocket);
begin
inherited Create(CreateSuspend);
ClientSocket:=Asocket;
end;
destructor TclientThread.Destroy;
var
i:integer;
begin
for i:=low(FS) to High(FS) do
FreeAndNil(FS);
FreeAndNil(FilesName);
inherited;
end;
procedure TclientThread.Endtrans;
begin
Form1.Label1.Caption:='Îļþ´«Êä½áÊø';
Form1.Button1.Caption:='½áÊø';
end;
procedure TclientThread.Execute;
var
WS:TWinSocketStream;
Bufferointer;
ReadText,SendText:String;
Start,Transing:Boolean;
ReadC:Integer;
const
ReadLen=4*1024;
begin
Start:=false;
Transing:=false;
Ws:=TWinSocketStream.Create(ClientSocket.Socket,6000);
try
while (not Terminated) and ClientSocket.Active do
begin
if Not Start then
begin
SendText:='AskForFileName';
Ws.Write(SendText[1],Length(SendText));
Start:=true;
end;
Buffer:=AllocMem(ReadLen);
if Ws.WaitForData(6000) then
begin
ReadC:=WS.Read(Buffer^,ReadLen);
if Transing then
begin
Inc(CurrLen,FS[Fileth].Write(Buffer^,Readc));
if CurrLen>=FSLen[Fileth] then
begin
CurrLen:=0;
Inc(Fileth);
end;
if Fileth=FilesName.Count then
begin
SendText:='FileIsover';
Ws.Write(SendText[1],Length(SendText));
synchronize(EndTrans);
Terminate;
end
else
begin
SendText:='AskForData';
WS.Write(SendText[1],Length(Sendtext));
end;
end
else
begin
ReadText:=PChar(Buffer);
if Pos('AskForFileName',ReadText)>0 then
begin
Delete(Readtext,1,length('AskForFileName,'));
FilesName:=TStringList.Create;
Filesname.Assign(StringToStrings(',',ReadText,True));
SendText:='AskForFileLen';
Ws.Write(SendText[1],Length(SendText));
end
else if Pos('AskForFileLen',ReadText)>0 then
begin
Delete(Readtext,1,length('AskForFileLen|'));
SetString(Readtext);
SendText:='AskForData';
Ws.Write(SendText[1],Length(SendText)+1);
Transing:=true;
Synchronize(StartTrans);
end;
end;
end;
FreeMem(Buffer);
end;
finally
ClientSocket.Close;
Ws.Free;
end;
end;
procedure TclientThread.SetString(InText: String);
var
Strs:TStrings;
i:integer;
begin
Strs:=TStringList.Create;
try
Strs.Assign(StringToStrings('|',Intext));
SetLength(FS,FilesName.Count);
SetLength(FSLen,Filesname.Count);
For i:=0 to FilesName.Count-1 do
begin
Fs:=TFileStream.Create(ExtractFilepath(ParamStr(0))+FilesName,fmCreate);
FSlen:=StrToInt(Strs);
inc(FileLen,FSLen);
end;
finally
Strs.Free;
end;
end;
procedure TclientThread.StartTrans;
begin
Form1.Label1.Caption:='¿ªÊ¼´«ÊäÎļþ,ÇëµÈ´ý';
Form1.Button1.Caption:='¿ªÊ¼';
end;
function TclientThread.StringToStrings(Sep, Str: String;Files:Boolean=false): TStrings;
var
i:integer;
begin
Result:=TStringList.Create;
i:=pos(Sep,Str);
while i<>0 do
begin
if Files then
Result.Add(ExtractFileName(Copy(Str,1,i-1)))
else
Result.Add(Copy(Str,1,i-1));
delete(Str,1,i-1+Length(sep));
I:=Pos(Sep,Str);
end;
if Files then
Result.Add(extractFileName(Str))
else
Result.Add(str);
end;
end.