serversocket多线程的问题!!(50分)

  • 主题发起人 主题发起人 samen
  • 开始时间 开始时间
S

samen

Unregistered / Unconfirmed
GUEST, unregistred user!
如何让SERVERSOCKET同一时刻传输多个文件?非要创建多线程吗?还是建立多个SERVERSOCKET?
请给段代码!!
 
:)可以肯定的说,一定要用多线程,没别的办法,你要同时处理多个请求,只有
用这个办法,
 
能给段代码吗?
 
这是我从HUBDOG的宝典上找到的。

使用TServerSocket构件提供多线程服务
对于一个socket来说,很容易提供一个侦听消息的多线程服务。Delphi自身也提供了这样的构件:TServerSocket。

不过这里边也需要一点小技巧。

为此,我们要做以下几件事:

-将TServerSocket加入main窗体中

-设置Servertype属性为stThreadBlocking

-生成一个新单元(如下)来包含服务线程



将下面的代码赋给OnGetThread事件响应函数

procedure TfrmMain.fSocketGetThread(Sender: TObject;

ClientSocket: TServerClientWinSocket;

var SocketThread: TServerClientThread);

begin

// 在每次一个新连接建立的时候为它生成一个新的TServerThread对象。

SocketThread := TServerThread.Create( FALSE, ClientSocket );

end;



下面是我自己生成的TServerThread对象代码.该对象从TServerClinetThread继承而来,包含从socket读写数据的代码。

unit serverthread;



interface



uses

windows, scktcomp, SysUtils, Classes, Forms;



type

EServerThread = class( Exception );

// TServerThread服务线程类是TServerClientThread的派生类

TServerThread = class( TServerClientThread )

private

fSocketStream : TWinSocketStream;

public

procedure ClientExecute; override;

// ClientExecute过程将覆盖TServerClientThread.ClientExecute过程

// 并包含实际执行的代码于线程开始时。

end;



implementation



procedure TServerThread.ClientExecute;

begin

inherited FreeOnTerminate := TRUE;

try

fSocketStream := TWinSocketStream.Create( ClientSocket,100000 );

// 设置100000毫秒的充许超时.

try

while ( not Terminated ) and ( ClientSocket.Connected ) do

try

// 在此处加入你对输入、读、写的等待

// 下面的示范你可以拿来照搬在此

except on e:exception do

begin

// 一旦错误发生就关闭并退出

ClientSocket.Close;

Terminate;

end;

end;

finally

fSocketStream.Free;

end;

except on e:exception do

begin

// 一旦错误发生就关闭并退出

ClientSocket.Close;

Terminate;

end;

end;

end;



一旦连接建立,线程需要等待数据到来.你可以使用下面的代码来等待数据:



if ( not Terminated ) and

( not fSocketStream.WaitForData( 1000000 ) ) then

begin

// 超时处理

end;

// 数据到达!



为了读取数据,我们需要建立一个数据缓冲区存取到达的数据,可以使用PByteArray或一个char型的数组.

在此例中我设置了一个名为fRequest的char型数组缓冲。此外我将其设为定长,其大小由REQUESTSIZE常量决定.



var

ac, readlen : integer;

begin

FillChar( fRequest, REQUESTSIZE, 0 );

ac := 0;

repeat

readlen := fSocketStream.Read( fRequest[ac],

1024 );

// 每次读取1024 bytes直到缓冲区满

ac := ac+readlen;

until ( readlen = 0 ) or ( ac = REQUESTSIZE );

end;

如果说readlen是 0 的话,说明我未收到任何数据.读函数的超时从TWinSocketStream.Create()执行后开始.如果说你不知道预期的数据量,你最好将超时设置得尽量小些.在大多数情况下 30 秒是上限.



当发送一个应答时,你应该很清楚客户端的行为.许多客户端仅仅等待一个应答包,一些则等待许多包.

在本例中,我只设置了一个客户端并只等待一个包,所以我们需要一次就将数据包发送出去。



fSocketStream.WriteBuffer( fRep, fReplySize );



fRep是应答缓冲区,fReplySize则是缓冲区大小.

 
如果要用多线程就要用阻塞方式,
不用多线程也是可以实现的啦,也不用创建多个serversocket,传送多个文件用一个循环就可以实现
 
后退
顶部