WSAIoctl在2.0的库中AcceptEx在1.0的库中,调用时,好像要重新动太加载1.0的地址,记的不太清楚,没有用过这样的设计,不过在那看到过的.
除非你要在连接时发附带数据。listen的 Socket用 WASAccept不行吗?
发现Indy10里面的:Line 3865
function ServiceQueryAcceptEx(sListenSocket, sAcceptSocket: TSocket;
lpOutputBuffer: Pointer; dwReceiveDataLength, dwLocalAddressLength,
dwRemoteAddressLength: DWORD; var lpdwBytesReceived: DWORD;
lpOverlapped: POverlapped): BOOL;
const GuidAcceptEx:TGuid=(D1:$b5367df1;D2:$cbac;D3:$11cf;D4
$95,$ca,$00,$80,$5f,$48,$a1,$92));
var LStatus : integer;
LAcceptEx : TAcceptExProc;
begin
LStatus:=WSAIoctl(sListenSocket, SIO_GET_EXTENSION_FUNCTION_POINTER, @GuidAcceptEx, sizeof(GuidAcceptEx),
@@LAcceptEx, sizeof(@LAcceptEx), nil, nil, nil);
if LStatus=0 then begin
result := LAcceptEx( sListenSocket, sAcceptSocket,
lpOutputBuffer, dwReceiveDataLength, dwLocalAddressLength,
dwRemoteAddressLength, lpdwBytesReceived, lpOverlapped);
end else begin
result := false;// WSAGetLastError returns 10022 when function is not supported
end;
End;
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2422504
转
在部分人都认为服务器上需要专门做一个线程去定时查看是否有实际已经不存在的连接,以便腾出
更多的资源供新的连接使用。这也并不是用完成端口模型编写的服务器才需要考虑的问题,用其它
模型编写的服务器一样存在这个问题。我没有测试过这样做的实效。无论如何,对完成端口模型中
总是有一个对连接的读操作请求一直没有返回,如果连接被某种因素断开应该会导致完成端口返回
一个字节数为零的读操作结果,同样会导致服务器断开此连接。我没有从Microsoft的相关文档上
看到有关的警告。
如果接受连接采用的是Microsoft扩展的AcceptEx函数而不是Accept或WSAAccept函数的话,需要考
虑防止DoS(拒绝服务)攻击,恶意客户占用连接后并不发送数据将导致函数AcceptEx的调用不能够正
常返回,而令合法客户无法连接进来。这是另外一个问题。这时候的轮询只需要考虑每一个守候着
的AcceptEx函数是否已连接以及连接的时间长短。长时间的连接而不发送数据的连接可以主动关闭
它。AcceptEx是唯一一个支持完成端口的接受连接函数。Accept/WSAAccept函数在与客户连接后,
才返回一个新的套接字,所以无法事先与完成端口关联。与而AcceptEx是事先创建一个套接字,在
还没有与客户连接的时候就与完成端口关联,一旦连接成功,便获得完成端口的通知。只可惜MS在
设计这个函数的时候一定要接收到部分数据才返回,所以给Dos攻击者提供了机会。不过我认为这样
可以省去监听线程,而设计一个不算繁忙的轮询线程一定会带来服务器性能的提升。