if SOCKET_ERROR=WSAAsyncSelect(sock, Handle,WM_SOCKET,FD_READ) then
Exit;
正常情况下可以
写成window服务时 Handle 如何设置请教!!!
Exit;
正常情况下可以
写成window服务时 Handle 如何设置请教!!!
解决方案 »
- RemObjects Pascal Script Delphi7
- 在哪儿能买到<DELPHI下深入WINDOWS核心编程>一书?
- 老是出现“不能操作一个关闭的数据库”的错误,为什么?
- 怎么写一个ASP的DLL 只要HELLO word 就行,谢谢谢谢谢谢
- 为CSDN的乱来喝彩
- 关于Delphi接收C DLL中struct返回值类型的问题
- 如何判断checkbox
- 使用SPCOMM中遇到的难题,高手帮忙(100分!!!)
- help!数据表
- 听说delphi6有bug,怎么办?应该不会客菜吧!
- 请教下Windows7下,使用Delphi2007 ADO报错找不到UDL配置文件
- 界面上放了几个TImage,如何让被点击的那个Image看起来与其它几个有所区分?
var
hEvent : WSAEvent;
ret : Integer;
ne : TWSANetworkEvents;
sock : TSocket;
adr : TSockAddrIn;
sMsg : String;
Index,
EventTotal : DWORD;
EventArray : Array [0..WSA_MAXIMUM_WAIT_EVENTS-1] of WSAEVENT;
begin
...socket...bind...
hEvent := WSACreateEvent();
WSAEventSelect( ListenSock, hEvent, FD_ACCEPT or FD_CLOSE );
...listen... while ( not Terminated ) do
begin
Index := WSAWaitForMultipleEvents( EventTotal, @EventArray[0], FALSE, WSA_INFINITE, FALSE );
FillChar( ne, sizeof(ne), 0 );
WSAEnumNetworkEvents( SockArray[Index-WSA_WAIT_EVENT_0], EventArray[Index-WSA_WAIT_EVENT_0], @ne ); if ( ne.lNetworkEvents and FD_ACCEPT ) > 0 then
begin
if ne.iErrorCode[FD_ACCEPT_BIT] <> 0 then
continue; ret := sizeof(adr);
sock := accept( SockArray[Index-WSA_WAIT_EVENT_0], adr, ret );
if EventTotal > WSA_MAXIMUM_WAIT_EVENTS-1 then//这里WSA_MAXIMUM_WAIT_EVENTS同样是64
begin
closesocket( sock );
continue;
end; hEvent := WSACreateEvent();
WSAEventSelect( sock, hEvent, FD_READ or FD_WRITE or FD_CLOSE );
SockArray[EventTotal] := sock;
EventArray[EventTotal] := hEvent;
Inc( EventTotal );
end; if ( ne.lNetworkEvents and FD_READ ) > 0 then
begin
if ne.iErrorCode[FD_READ_BIT] <> 0 then
continue;
FillChar( RecvBuf[0], PACK_SIZE_RECEIVE, 0 );
ret := recv( SockArray[Index-WSA_WAIT_EVENT_0], RecvBuf[0], PACK_SIZE_RECEIVE, 0 );
......
end;
end;
end;
Listen线程和WSAEventSelect模型一模一样,Recv/Send线程则完全不同: procedure TOverlapThread.Execute;
var
dwTemp : DWORD;
ret : Integer;
Index : DWORD;
begin
...... while ( not Terminated ) do
begin
Index := WSAWaitForMultipleEvents( FLinks.Count, @FLinks.Events[0], FALSE, RECV_TIME_OUT, FALSE );
Dec( Index, WSA_WAIT_EVENT_0 );
if Index > WSA_MAXIMUM_WAIT_EVENTS-1 then //超时或者其他错误
continue; WSAResetEvent( FLinks.Events[Index] );
WSAGetOverlappedResult( FLinks.Sockets[Index], FLinks.pOverlaps[Index], @dwTemp, FALSE,FLinks.pdwFlags[Index]^ ); if dwTemp = 0 then //连接已经关闭
begin
......
continue;
end else
begin
fmMain.ListBox1.Items.Add( FLinks.pBufs[Index]^.buf );
end; //初始化缓冲区
FLinks.pdwFlags[Index]^ := 0;
FillChar( FLinks.pOverlaps[Index]^, sizeof(WSAOVERLAPPED), 0 );
FLinks.pOverlaps[Index]^.hEvent := FLinks.Events[Index];
FillChar( FLinks.pBufs[Index]^.buf^, BUFFER_SIZE, 0 ); //递一个接收数据请求
WSARecv( FLinks.Sockets[Index], FLinks.pBufs[Index], 1, FLinks.pdwRecvd[Index]^, FLinks.pdwFlags[Index]^, FLinks.pOverlaps[Index], nil );
end;
end;
当应用程序中需要管理多余64个套接字时,就需要额外创建线程
我倒建议用消息的WSAAsyncSelect模型