procedure TServerThread.ClientExecute;
var
pStream:TWinSocketStream;
buffer:Pointer;
readText,SendText:string;
i:integer;
Const
{读客户端令牌时使用的缓冲区大小,因为它们都是一些字符串,所以定义为1024byte足够了}
ReadLen=1024;
begin
{创建连接流对象,以便和客户端交流}
pStream:=TWinSocketStream.Create(ClientSocket,60000);
try
{ClientSocket是TServerClientThread 类内置的一个对象,它是和客户端连接的套接字}
while (not Terminated) and ClientSocket.Connected do
begin
try
{分配读数据缓冲区}
Buffer:=AllocMem(readLen);
if PStream.WaitForData(6000) then
begin
pStream.Read(Buffer^,ReadLen); ///读取客户端发送data,数据是从缓存区中读取。 readText:=Pchar(Buffer);
FreeMem(buffer);
//客户端请求验证是否有可以更新的文件
if ReadText = Key_Clt[1] then
begin
Synchronize(listItemAdd);//多线程中同步信息需要调用的方法。
SendText:=Key_Srv[1]+stringstostring(FilesNameSepstr,filesName,true);
{特别注意SendText后应该加上索引1,指定write方法从SendText第一个字符
开始读,否则默认从0开始}
pStream.Write(SendText[1],length(sendtext)+1);//向客户端写数据
end
except
errorRaise:=true;
Terminate;
end;
end;
finally
pstream.Free;
ClientSocket.Close;
end;
end;
由于Socket选择 使用ctBlock的方式,所以在接收、发送数据时,就不能依靠在OnRead,OnWrite中读取和写入数据了,因为该事件在ctBlock下根本就不能被触发。
解决的方法就是不间断的监听线程
while (not Terminated) and ClientSocket.Connected do
begin
end;
读取数据的时机:if PStream.WaitForData(6000) then
begin
end;
转自:http://gykthh.blog.163.com/blog/static/6453464200852710710790/
-----------------------------------------------------------------------------------------------------------------------------
{ TFileServerThread }
public
procedure ClientExecute; override;
end;
var
Data : array[0..1023] of char;
RecText : string;
SocketStream : TWinSocketStream;
begin
Try
SocketStream := TWinSocketStream.Create(ClientSocket, 30000);
Try
FillChar(Data, SizeOf(Data), 0);
If SocketStream.Read(Data, SizeOf(Data)) = 0 Then
Begin
// If we didn‘t get any data after xx seconds then close the connection
ClientSocket.SendText(‘Timeout on Server‘+#13#10);
//Wait a little time to allow sending of text before disconnect
sleep(1);
ClientSocket.Close;
Terminate;
End;
RecText := Data;
If Length(RecText) > 2 Then
Delete(RecText, Pos(#13#10, RecText), 2); // Delete #13#10
If ClientSocket.Connected Then
Begin
ClientSocket.SendText(RecText);
SendMessage(Form1.Listbox1.Handle, LB_ADDSTRING, 0, Integer(PChar(RecText)));
PostMessage(Form1.Handle, CM_INCCOUNT, 0, 0);
End;
Finally
SocketStream.Free;
End;
Except
HandleException;
End;
end;
ClientSocket: TServerClientWinSocket;
var SocketThread: TServerClientThread);
begin
SocketThread := TFileServerThread.Create(False, ClientSocket);
end;
-----------------------------------------------------------------------------------------------------------------------------
delphi的帮助中有Writing client threads 和 Writing server threads代码示例。
procedure
TMyClientThread.Execute;
var
TheStream: TWinSocketStream;
buffer:
string;
begin
{ create a TWinSocketStream for reading and writing }
TheStream := TWinSocketStream.Create(ClientSocket1.Socket, 60000);
try
{ fetch and process commands until the connection or thread is terminated
}
while (not Terminated) and (ClientSocket1.Active) do
begin
try
GetNextRequest(buffer); { GetNextRequest must be a thread-safe
method }
{ write the request to the server }
TheStream.Write(buffer, Length(buffer) + 1);
{ continue the
communication (e.g. read a response from the server) }
...
except
if not(ExceptObject is EAbort) then
Synchronize(HandleThreadException); { you must write HandleThreadException }
end;
end;
finally
TheStream.free;
end;
end;
procedure TMyServerThread.ClientExecute;
var
Stream :
TWinSocketStream;
Buffer : array[0 .. 9] of Char;
begin
{ make
sure connection is active }
while (not Terminated) and
ClientSocket.Connected do
begin
try
Stream :=
TWinSocketStream.Create(ClientSocket, 60000);
try
FillChar(Buffer, 10, 0); { initialize the buffer }
{ give the client
60 seconds to start writing }
if Stream.WaitForData(60000) then
begin
if Stream.Read(Buffer, 10) = 0 then { if can‘t
read in 60 seconds }
ClientSocket.Close; { close
the connection }
{ now process the request }
...
end
else
ClientSocket.Close; { if client doesn‘t
start, close }
finally
Stream.Free;
end;
except
HandleException;
end;
end;
end;