最简单的WSAEventSelect模型(注意注释的地方)
程序员文章站
2022-03-02 15:30:49
...
// Win32SocketTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "winsock2.h"
//#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"Ws2_32.lib")
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
int arg = 1000;
int theOp = ~arg + 1;
int theOp2 = ~theOp + 1;
//启动socket
WSADATA data;
WSAStartup(MAKEWORD(2,2),&data);
//设置服务器地址
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(5000);
addr.sin_addr.S_un.S_un_b.s_b1 = 113;
addr.sin_addr.S_un.S_un_b.s_b2 = 90;
addr.sin_addr.S_un.S_un_b.s_b3 = 50;
addr.sin_addr.S_un.S_un_b.s_b4 = 170;
int len = sizeof(addr);
//创建socket
SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
//绑定socket
bind(s,(sockaddr*)&addr,sizeof(addr));
while(true)
{
//监听socket
listen(s,SOMAXCONN);
//创建与socket关联的事件
WSAEVENT event = WSACreateEvent();
WSAEventSelect(s,event,FD_ACCEPT | FD_CLOSE);
//等待事件发生
//////////////////////////////////////////////////////////////////////////
//阻塞!必须建立线程去处理。。以后改进。
DWORD nResult = WaitForSingleObject(event, INFINITE);
if (nResult == WAIT_OBJECT_0)
{
//查询是什么事件发生了。
WSANETWORKEVENTS ne;
WSAEnumNetworkEvents(s,event,&ne);
if (ne.lNetworkEvents&FD_ACCEPT)
{
//为这个客户端建立一个套接字用来收发数据。
SOCKADDR_IN clientAddr;
int addrlen = sizeof(clientAddr);
SOCKET sClient = accept(s, (sockaddr*)&clientAddr, &addrlen);
//////////////////////////////////////////////////////////////////////////
/////阻塞!必须建立线程去处理。。以后改进。
WSAEVENT eventWriteRead = WSACreateEvent();
WSAEventSelect(sClient,eventWriteRead,FD_WRITE|FD_READ|FD_CLOSE);
while (true)
{
WaitForSingleObject(eventWriteRead,INFINITE);
{
//查询是什么事件发生了。
WSANETWORKEVENTS ne;
WSAEnumNetworkEvents(sClient,eventWriteRead,&ne);
if (ne.lNetworkEvents&FD_WRITE)
{
char a[1000];
memset(a,0,sizeof(a));
std::cin>>a;
send(sClient, a, sizeof(a),0);
}
else if (ne.lNetworkEvents&FD_READ)
{
char buf[1000];
buf[999] = 0;
recv( sClient,buf,len,0);
std::cout<<buf;
}
else if (ne.lNetworkEvents&FD_CLOSE)
{
closesocket(s);
}
}
WSAResetEvent(eventWriteRead);
}
//////////////////////////////////////////////////////////////////////////
}
else
{
closesocket(s);
}
}
//////////////////////////////////////////////////////////////////////////
WSAResetEvent(event);
}
return 0;
}
要改进的地方
1。阻塞的地方waiforsingle改为waitformultiple,并且用线程去处理。
2。用短连接代替长连接来处理。收到一个完整的业务包之后,进行关闭。