今天又琢磨了一下WSAEventSelect模型:跟WSAAsyncSelect比起来,不用跟窗口消息挂钩,当然适用面就更广了,还是不错的,里面需要用到的新的东西有,全大写的是结构体,否则是函数:
WSAEventSelect
WSAWaitForMultipleEvents
WSAEVENT
WSANETWORKEVENTS
WSAEnumNetworkEvents
WSACreateEvent
下面是根据这个写的一个echo服务端
//Author:mungco
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#define PORT 8888
#define DATA_BUFSIZE 1024
SOCKET Socket[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT Event[WSA_MAXIMUM_WAIT_EVENTS];
DWORD EventTotal = 0;
DWORD Index;
void InitSocket()
{
WSADATA wsaData;
int ret;
if((ret=WSAStartup(MAKEWORD(2,2),&wsaData))!=0){
printf("WSAStartup failed with error:%d\n",ret);
WSACleanup();
return;
}
}
int main(int argc , char *argv[])
{
InitSocket();
SOCKET ListenSocket,AcceptSocket;
SOCKADDR_IN InternetAddr;
DWORD Flags;
DWORD ThreadId;
DWORD RecvBytes;
int Ret;
char buffer[DATA_BUFSIZE];
char sendbuffer[]="Your message has been received by server!";
int AddrSize=sizeof(SOCKADDR);
if((ListenSocket=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED))==INVALID_SOCKET){
printf("Failed to get a socket %d\n",WSAGetLastError());
return 1;
}
InternetAddr.sin_family=AF_INET;
InternetAddr.sin_addr.s_addr=htons(INADDR_ANY);
InternetAddr.sin_port=htons(PORT);
if(bind(ListenSocket,(SOCKADDR*)&InternetAddr,AddrSize)==SOCKET_ERROR){
printf("bind Error:%d\n",WSAGetLastError());
return 1;
}
WSAEVENT NewEvent=WSACreateEvent();
WSAEventSelect(ListenSocket,NewEvent,FD_ACCEPT|FD_CLOSE);
if(listen(ListenSocket,5)==SOCKET_ERROR){
printf("listen failed with error:%d\n",WSAGetLastError());
return 1;
}
Socket[EventTotal]=ListenSocket;
Event[EventTotal]=NewEvent;
EventTotal++;
//Setup the listening socket for connections.
for(;;){
Index=WSAWaitForMultipleEvents(EventTotal,Event,FALSE,WSA_INFINITE,FALSE);
WSANETWORKEVENTS NetworkEvents;
WSAEnumNetworkEvents(Socket[Index-WSA_WAIT_EVENT_0],Event[Index-WSA_WAIT_EVENT_0],&NetworkEvents);
if(NetworkEvents.lNetworkEvents & FD_ACCEPT){
if(NetworkEvents.iErrorCode[FD_ACCEPT_BIT]!=0){
printf("FD_ACCEPT failed with error :%d\n",NetworkEvents.iErrorCode[FD_ACCEPT_BIT]);
break;
}
if((AcceptSocket=accept(Socket[Index-WSA_WAIT_EVENT_0],NULL,NULL))==SOCKET_ERROR){
printf("Socket Error:%d\n",WSAGetLastError());
break;
}
if(EventTotal>WSA_MAXIMUM_WAIT_EVENTS){
printf("Too many connections");
return 1;
}
NewEvent = WSACreateEvent();
WSAEventSelect(AcceptSocket,NewEvent,FD_READ|FD_WRITE|FD_CLOSE);
Event[EventTotal]=NewEvent;
Socket[EventTotal]=AcceptSocket;
EventTotal++;
printf("Socket %d connected\n",AcceptSocket);
}
if(NetworkEvents.lNetworkEvents & FD_READ){
if(NetworkEvents.iErrorCode[FD_READ_BIT]!=0){
printf("FD_READ failed with error %d\n",NetworkEvents.iErrorCode[FD_READ_BIT]);
break;
}
int count=recv(Socket[Index-WSA_WAIT_EVENT_0],buffer,sizeof(buffer),0);
if(count==0){
printf("Socket disconnected\n");
break;
}
else if(count<0){
printf("recv failed with error:%d\n",WSAGetLastError());
break;
}
else{
buffer[count]='\0';
printf("%d:%s\n",Socket[Index-WSA_WAIT_EVENT_0],buffer);
send(Socket[Index-WSA_WAIT_EVENT_0],sendbuffer,strlen(sendbuffer)+1,0);
}
}
if(NetworkEvents.lNetworkEvents & FD_WRITE){
if(NetworkEvents.iErrorCode[FD_WRITE_BIT]!=0){
printf("FD_WRITE failed with error %d\n",NetworkEvents.iErrorCode[FD_WRITE_BIT]);
break;
}
printf("Why should I write!\n");
// buffer[0]='\0';
// send(Socket[Index-WSA_WAIT_EVENT_0],buffer,strlen(buffer),0);
}
if(NetworkEvents.lNetworkEvents & FD_CLOSE){
if(NetworkEvents.iErrorCode[FD_CLOSE_BIT]!=0){
printf("FD_CLOSE failed with error %d\n",NetworkEvents.iErrorCode[FD_CLOSE_BIT]);
break;
}
closesocket(Socket[Index-WSA_WAIT_EVENT_0]);
Socket[Index-WSA_WAIT_EVENT_0]=Socket[--EventTotal];
}
}
}
本文介绍如何使用WSAEventSelect模型实现一个简单的Echo服务端程序。该模型适用于Windows平台,通过等待多个事件来处理网络连接和数据收发。文章提供了完整的代码示例,演示了从初始化套接字到接收和发送数据的过程。
2450

被折叠的 条评论
为什么被折叠?



