以下是WSAEventSelect模型(服务器),但是,发现了问题:
1.如果客户端不给服务器发送数据,那么,可以正常退出(即,可得到FD_CLOSE事件)
2.如果客户端给服务器发送数据了,而且,客户端使用closesocket退出,在服务器端,却无法正常响应FD_CLOSE。也不知道为什么!有劳各位高人了!谢谢!代码如下:#include "initsock.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"WS2_32")CInitSock theSock;//加载套接字版本类的对象void main()
{
SOCKET sockArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT eventArr[WSA_MAXIMUM_WAIT_EVENTS];
WSANETWORKEVENTS networkEvent;
WSAEVENT newEvent;
SOCKADDR_IN netAddr;
SOCKET sockAcpt, sockLstn;
int eventTotal=0;
int index, i;
sockLstn=socket(PF_INET,SOCK_STREAM,0);
netAddr.sin_family=AF_INET;
netAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
netAddr.sin_port=htons(4567);
bind(sockLstn,(SOCKADDR*)&netAddr,sizeof(netAddr));
newEvent=WSACreateEvent();
WSAEventSelect(sockLstn,newEvent,FD_ACCEPT|FD_CLOSE);
listen(sockLstn,5);
sockArr[eventTotal]=sockLstn;
eventArr[eventTotal]=newEvent;
eventTotal++;
while (TRUE)
{
index=WSAWaitForMultipleEvents(eventTotal,eventArr,FALSE,WSA_INFINITE,FALSE);
index-=WSA_WAIT_EVENT_0;
for (i=index; i<eventTotal; i++)
{
index=WSAWaitForMultipleEvents(1,&eventArr[i],TRUE,0,FALSE);//0,1000
if ((WSA_WAIT_FAILED==index)||(WSA_WAIT_TIMEOUT==index))
{
continue ;
}
else
{
index=i;
WSAEnumNetworkEvents(sockArr[index],eventArr[index],&networkEvent);
if (networkEvent.lNetworkEvents & FD_ACCEPT)//FD_ACCEPT//
{
if (0!=networkEvent.iErrorCode[FD_ACCEPT_BIT])
{
printf("FD_ACCEPT failed with error %d \n",
networkEvent.iErrorCode[FD_ACCEPT_BIT]);
break;
}
sockAcpt=accept(sockArr[index],NULL,NULL);
if (eventTotal>WSA_MAXIMUM_WAIT_EVENTS)
{
printf("Too many connections!");
closesocket(sockAcpt);
break;
}
newEvent=WSACreateEvent();
WSAEventSelect(sockAcpt,newEvent,FD_READ|FD_WRITE|FD_CLOSE);
eventArr[eventTotal]=newEvent;
sockArr[eventTotal]=sockAcpt;
eventTotal++;
printf("Socket %d connected \n",eventTotal);
}
else if (networkEvent.lNetworkEvents & FD_READ)//FD_READ//
{
if (0!=networkEvent.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d \n",
networkEvent.iErrorCode[FD_READ_BIT]);
break;
}
printf("FD_READ \n");
char buff[512];
int nRet=::recv(sockArr[index],buff,512,0);
}
else if (networkEvent.lNetworkEvents & FD_WRITE)//FD_WRITE//
{
if (0!=networkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d \n",
networkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
printf("FD_WRITE \n");
}
else if (networkEvent.lNetworkEvents & FD_CLOSE)//FD_CLOSE//
{
if (0!=networkEvent.iErrorCode[FD_CLOSE_BIT])
{
printf("FD_CLOSE failed with error %d \n",
networkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(sockArr[index]);
WSACloseEvent(eventArr[index]);
for (int j=index;j<eventTotal-1;j++)
{
sockArr[j]=sockArr[j+1];
eventArr[j]=eventArr[j+1];
}
eventTotal--;
printf("FD_CLOSE \n");
}
}
}
}
}
1.如果客户端不给服务器发送数据,那么,可以正常退出(即,可得到FD_CLOSE事件)
2.如果客户端给服务器发送数据了,而且,客户端使用closesocket退出,在服务器端,却无法正常响应FD_CLOSE。也不知道为什么!有劳各位高人了!谢谢!代码如下:#include "initsock.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"WS2_32")CInitSock theSock;//加载套接字版本类的对象void main()
{
SOCKET sockArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT eventArr[WSA_MAXIMUM_WAIT_EVENTS];
WSANETWORKEVENTS networkEvent;
WSAEVENT newEvent;
SOCKADDR_IN netAddr;
SOCKET sockAcpt, sockLstn;
int eventTotal=0;
int index, i;
sockLstn=socket(PF_INET,SOCK_STREAM,0);
netAddr.sin_family=AF_INET;
netAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
netAddr.sin_port=htons(4567);
bind(sockLstn,(SOCKADDR*)&netAddr,sizeof(netAddr));
newEvent=WSACreateEvent();
WSAEventSelect(sockLstn,newEvent,FD_ACCEPT|FD_CLOSE);
listen(sockLstn,5);
sockArr[eventTotal]=sockLstn;
eventArr[eventTotal]=newEvent;
eventTotal++;
while (TRUE)
{
index=WSAWaitForMultipleEvents(eventTotal,eventArr,FALSE,WSA_INFINITE,FALSE);
index-=WSA_WAIT_EVENT_0;
for (i=index; i<eventTotal; i++)
{
index=WSAWaitForMultipleEvents(1,&eventArr[i],TRUE,0,FALSE);//0,1000
if ((WSA_WAIT_FAILED==index)||(WSA_WAIT_TIMEOUT==index))
{
continue ;
}
else
{
index=i;
WSAEnumNetworkEvents(sockArr[index],eventArr[index],&networkEvent);
if (networkEvent.lNetworkEvents & FD_ACCEPT)//FD_ACCEPT//
{
if (0!=networkEvent.iErrorCode[FD_ACCEPT_BIT])
{
printf("FD_ACCEPT failed with error %d \n",
networkEvent.iErrorCode[FD_ACCEPT_BIT]);
break;
}
sockAcpt=accept(sockArr[index],NULL,NULL);
if (eventTotal>WSA_MAXIMUM_WAIT_EVENTS)
{
printf("Too many connections!");
closesocket(sockAcpt);
break;
}
newEvent=WSACreateEvent();
WSAEventSelect(sockAcpt,newEvent,FD_READ|FD_WRITE|FD_CLOSE);
eventArr[eventTotal]=newEvent;
sockArr[eventTotal]=sockAcpt;
eventTotal++;
printf("Socket %d connected \n",eventTotal);
}
else if (networkEvent.lNetworkEvents & FD_READ)//FD_READ//
{
if (0!=networkEvent.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d \n",
networkEvent.iErrorCode[FD_READ_BIT]);
break;
}
printf("FD_READ \n");
char buff[512];
int nRet=::recv(sockArr[index],buff,512,0);
}
else if (networkEvent.lNetworkEvents & FD_WRITE)//FD_WRITE//
{
if (0!=networkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d \n",
networkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
printf("FD_WRITE \n");
}
else if (networkEvent.lNetworkEvents & FD_CLOSE)//FD_CLOSE//
{
if (0!=networkEvent.iErrorCode[FD_CLOSE_BIT])
{
printf("FD_CLOSE failed with error %d \n",
networkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(sockArr[index]);
WSACloseEvent(eventArr[index]);
for (int j=index;j<eventTotal-1;j++)
{
sockArr[j]=sockArr[j+1];
eventArr[j]=eventArr[j+1];
}
eventTotal--;
printf("FD_CLOSE \n");
}
}
}
}
}
//#include "initsock.h"
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"WS2_32")//CInitSock theSock;//加载套接字版本类的对象#define SERVER_PORT 4567void main()
{
SOCKET sockArr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT eventArr[WSA_MAXIMUM_WAIT_EVENTS];
WSANETWORKEVENTS networkEvent;
WSAEVENT newEvent;
SOCKADDR_IN netAddr;
SOCKET sockAcpt, sockLstn;
int eventTotal=0;
int index, i; // must load socket engine
WSADATA wd;
WSAStartup(MAKEWORD(2,2), &wd);
sockLstn=socket(PF_INET,SOCK_STREAM,0);
netAddr.sin_family=AF_INET;
netAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
netAddr.sin_port=htons(SERVER_PORT); printf("server started success, port = %d\r\n", SERVER_PORT);
bind(sockLstn,(SOCKADDR*)&netAddr,sizeof(netAddr));
// WSAEventSelect will be enabled as you operate for it anywhere
// and the recently one will take effect instead of the prior one.
newEvent=WSACreateEvent();
WSAEventSelect(sockLstn,newEvent,FD_ACCEPT|FD_CLOSE|FD_READ|FD_WRITE);
listen(sockLstn,5);
sockArr[eventTotal]=sockLstn;
eventArr[eventTotal]=newEvent;
eventTotal++;
while (TRUE)
{
index=WSAWaitForMultipleEvents(eventTotal,eventArr,FALSE,WSA_INFINITE,FALSE);
index-=WSA_WAIT_EVENT_0;
for (i=index; i<eventTotal; i++)
{
index=WSAWaitForMultipleEvents(1,&eventArr[i],TRUE,0,FALSE);//0,1000
if ((WSA_WAIT_FAILED==index)||(WSA_WAIT_TIMEOUT==index))
{
continue ;
}
else
{
index=i;
WSAEnumNetworkEvents(sockArr[index],eventArr[index],&networkEvent);
if (networkEvent.lNetworkEvents & FD_ACCEPT)//FD_ACCEPT//
{
if (0!=networkEvent.iErrorCode[FD_ACCEPT_BIT])
{
printf("FD_ACCEPT failed with error %d \n",
networkEvent.iErrorCode[FD_ACCEPT_BIT]);
break;
}
SOCKADDR_IN addr;
int nLen = sizeof(addr);
sockAcpt=accept(sockArr[index], (SOCKADDR *)&addr, &nLen);
printf("Accept client: %s, port: %d\r\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
if (eventTotal>WSA_MAXIMUM_WAIT_EVENTS)
{
printf("Too many connections!");
closesocket(sockAcpt);
break;
}
newEvent=WSACreateEvent();
WSAEventSelect(sockAcpt,newEvent,FD_READ|FD_WRITE|FD_CLOSE);
eventArr[eventTotal]=newEvent;
sockArr[eventTotal]=sockAcpt;
eventTotal++;
printf("Socket %d connected \n",eventTotal);
}
else if (networkEvent.lNetworkEvents & FD_READ)//FD_READ//
{
printf("FD_READ!\r\n");
if (0!=networkEvent.iErrorCode[FD_READ_BIT])
{
printf("FD_READ failed with error %d \n",
networkEvent.iErrorCode[FD_READ_BIT]);
break;
}
printf("FD_READ \n");
char buff[512];
int nRet=::recv(sockArr[index],buff,512,0);
}
else if (networkEvent.lNetworkEvents & FD_WRITE)//FD_WRITE//
{
printf("FD_WRITE!\r\n");
if (0!=networkEvent.iErrorCode[FD_WRITE_BIT])
{
printf("FD_WRITE failed with error %d \n",
networkEvent.iErrorCode[FD_WRITE_BIT]);
break;
}
printf("FD_WRITE \n");
}
else if (networkEvent.lNetworkEvents & FD_CLOSE)//FD_CLOSE//
{
printf("FD_CLOSE!\r\n");
if (0!=networkEvent.iErrorCode[FD_CLOSE_BIT])
{
printf("FD_CLOSE failed with error %d \n",
networkEvent.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(sockArr[index]);
WSACloseEvent(eventArr[index]);
for (int j=index;j<eventTotal-1;j++)
{
sockArr[j]=sockArr[j+1];
eventArr[j]=eventArr[j+1];
}
eventTotal--;
printf("FD_CLOSE \n");
}
}
}
}
}