M
metalchen
Unregistered / Unconfirmed
GUEST, unregistred user!
客户段可以连接到服务棋.但是,无法接收ACCEPT,read等事件通知.后来发现WSAWaitForMultipleEvents总是还回-1啊..很是奇怪..
if WSAStartup($0202,FWsdata)=SOCKET_ERROR then
begin
raise Exception.Create('WSAStartUp error'+IntToStr(WSAGetLastError));
exit;
end;
FServerSock:=socket(AF_INET,SOCK_STREAM,0);
if FServerSock=0 then
raise Exception.Create('Socket error'+IntToStr(WSAGetLastError));
FillChar(FSocketAddr,sizeof(FSocketAddr),#0);
FSocketAddr.sin_family:=AF_INET;
FSocketAddr.sin_port:=htons(FPort);
FSocketAddr.sin_addr.S_addr:=INADDR_ANY;
if bind(FServerSock,@FSocketAddr,sizeof(FSocketAddr))<0 then
raise Exception.Create('open sock error:'+IntToStr(WSAGetLastError));
//**********************************创建Event对象绑定FServerSocket******************
//*********************************
FServerSockEvent:=WSACreateEvent;
WSAEventSelect(FServerSock,FServerSockEvent,FD_ACCEPT or FD_CLOSE);
FArryEvent[FTotalEvent]:=FServerSockEvent;
FArrySocket[FTotalEvent]:=FServerSock;
Inc(FTotalEvent);
//所以处理完毕以后就开始listen;
if listen(FServerSock,5)<>0 then
raise Exception.Create('open sock error:'+IntToStr(WSAGetLastError));
while (not Terminated) do
begin
//W S AWa i t F o r M u l t i p l e E v e n t s收到一个事件对象的网络事件通知,便会返回一个值,指
//出造成函数返回的事件对象
FIndex:=WSAWaitForMultipleEvents(FEventTotal,@FArryEvent[0],False,WSA_INFINITE,False);
//这样一来,我们的应用程序便可引用事件数组中已传信的事件,
//并检索与那个事件对应的套接字,判断到底是在哪个套接字上,发生了什么网络事件类型。
//对事件数组中的事件进行引用时,应该用 W S AWa i t F o r M u l t i p l e E v e n t s的返回值,减去预定义
//值W S A _ WA I T _ E V E N T _ 0,得到具体的引用值(即索引位置)。
FillChar(FWSANetworkEvnt,sizeof(FWSANetworkEvnt),#0);
//知道了造成网络事件的套接字后,接下来可调用 W S A E n u m N e t w o r k E v e n t s函数,调查发
//生了什么类型的网络事件
WSAEnumNetworkEvents(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FArryEvent[FIndex-WSA_WAIT_EVENT_0],@FWSANetworkEvnt);
if (FWSANetworkEvnt.lNetworkEvents and FD_Accept )>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_ACCEPT_Bit]<>0 then
continue;
FClientAddrSize:=sizeof(FClientAddr);
FClientSock:=accept(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FClientAddr,FClientAddrSize);
if FEventTotal>WSA_MAXIMUM_WAIT_EVENTS then
begin
closesocket(FClientSock);
continue;
end;
FClientEvent:=WSACreateEvent;
WSAEventSelect(FClientSock,FClientEvent,FD_READ or FD_WRITE or FD_CLOSE);
FArryEvent[FEventTotal]:=FClientEvent;
FArrySocket[FEventTotal]:=FClientSock;
Inc(FEventTotal);
if Assigned(FValueOnAccept) then FValueOnAccept(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_READ)>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_READ_BIT]<>0 then
continue;
FillChar(FRecvBuf,Page_Max_Size,#0);
recv(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FRecvBuf,Page_Max_Size,0);
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_WRITE)>0 then
begin
if (FWSANetworkEvnt.lNetworkEvents and FD_WRITE)<>0 then
continue;
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_CLOSE)>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_CLOSE_BIT]<>0 THEN
continue;
closesocket(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
if Assigned(FValueOnClose) then FValueOnClose(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
end;
end;
end;
if WSAStartup($0202,FWsdata)=SOCKET_ERROR then
begin
raise Exception.Create('WSAStartUp error'+IntToStr(WSAGetLastError));
exit;
end;
FServerSock:=socket(AF_INET,SOCK_STREAM,0);
if FServerSock=0 then
raise Exception.Create('Socket error'+IntToStr(WSAGetLastError));
FillChar(FSocketAddr,sizeof(FSocketAddr),#0);
FSocketAddr.sin_family:=AF_INET;
FSocketAddr.sin_port:=htons(FPort);
FSocketAddr.sin_addr.S_addr:=INADDR_ANY;
if bind(FServerSock,@FSocketAddr,sizeof(FSocketAddr))<0 then
raise Exception.Create('open sock error:'+IntToStr(WSAGetLastError));
//**********************************创建Event对象绑定FServerSocket******************
//*********************************
FServerSockEvent:=WSACreateEvent;
WSAEventSelect(FServerSock,FServerSockEvent,FD_ACCEPT or FD_CLOSE);
FArryEvent[FTotalEvent]:=FServerSockEvent;
FArrySocket[FTotalEvent]:=FServerSock;
Inc(FTotalEvent);
//所以处理完毕以后就开始listen;
if listen(FServerSock,5)<>0 then
raise Exception.Create('open sock error:'+IntToStr(WSAGetLastError));
while (not Terminated) do
begin
//W S AWa i t F o r M u l t i p l e E v e n t s收到一个事件对象的网络事件通知,便会返回一个值,指
//出造成函数返回的事件对象
FIndex:=WSAWaitForMultipleEvents(FEventTotal,@FArryEvent[0],False,WSA_INFINITE,False);
//这样一来,我们的应用程序便可引用事件数组中已传信的事件,
//并检索与那个事件对应的套接字,判断到底是在哪个套接字上,发生了什么网络事件类型。
//对事件数组中的事件进行引用时,应该用 W S AWa i t F o r M u l t i p l e E v e n t s的返回值,减去预定义
//值W S A _ WA I T _ E V E N T _ 0,得到具体的引用值(即索引位置)。
FillChar(FWSANetworkEvnt,sizeof(FWSANetworkEvnt),#0);
//知道了造成网络事件的套接字后,接下来可调用 W S A E n u m N e t w o r k E v e n t s函数,调查发
//生了什么类型的网络事件
WSAEnumNetworkEvents(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FArryEvent[FIndex-WSA_WAIT_EVENT_0],@FWSANetworkEvnt);
if (FWSANetworkEvnt.lNetworkEvents and FD_Accept )>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_ACCEPT_Bit]<>0 then
continue;
FClientAddrSize:=sizeof(FClientAddr);
FClientSock:=accept(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FClientAddr,FClientAddrSize);
if FEventTotal>WSA_MAXIMUM_WAIT_EVENTS then
begin
closesocket(FClientSock);
continue;
end;
FClientEvent:=WSACreateEvent;
WSAEventSelect(FClientSock,FClientEvent,FD_READ or FD_WRITE or FD_CLOSE);
FArryEvent[FEventTotal]:=FClientEvent;
FArrySocket[FEventTotal]:=FClientSock;
Inc(FEventTotal);
if Assigned(FValueOnAccept) then FValueOnAccept(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_READ)>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_READ_BIT]<>0 then
continue;
FillChar(FRecvBuf,Page_Max_Size,#0);
recv(FArrySocket[FIndex-WSA_WAIT_EVENT_0],FRecvBuf,Page_Max_Size,0);
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_WRITE)>0 then
begin
if (FWSANetworkEvnt.lNetworkEvents and FD_WRITE)<>0 then
continue;
end;
if (FWSANetworkEvnt.lNetworkEvents and FD_CLOSE)>0 then
begin
if FWSANetworkEvnt.iErrorCode[FD_CLOSE_BIT]<>0 THEN
continue;
closesocket(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
if Assigned(FValueOnClose) then FValueOnClose(FArrySocket[FIndex-WSA_WAIT_EVENT_0]);
end;
end;
end;