随笔——控制台下的Select模型的模板

本文介绍了在Winsock编程中,如何在控制台应用中使用select模型,以避免界面未响应的问题。利用select模型可以在不依赖多线程的情况下实现高效网络通信。提供了一个控制台下的Select模型模板,而对于MFC应用下的实现,则建议参考后续文章。
摘要由CSDN通过智能技术生成

Winsock编程中select模型是个好东西,不用多线程的话这是个很好的选择。

MFC编程中,如果还是用简单的阻塞模型while(1)的话,很可能会发生界面未响应,变白down掉的情况。所以这个时候select模型就显得十分重要。

这是控制台下的Select模型的模板,MFC下的select请看下一篇文章

#include<winsock2.h>
#include<ws2tcpip.h>
#include<windows.h>
#include<stdio.h>
#include<conio.h>
#pragma comment(lib,"ws2_32.lib")
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT 27015

int _tmain()
{
	WSADATA wsaData;
	int iResult;
	SOCKET SeverSocket = INVALID_SOCKET;
	iResult = WSAStartup(MAKEWORD(2,2),&wsaData);
	if(iResult != 0)
	{
		//WSAStartup failed!\r\n
		return 1;
	}
	SeverSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_IP);
	if(SeverSocket == INVALID_SOCKET)
	{
		//socket failed!
		WSACleanup();
		return 1;
	}
	SOCKADDR_IN addrServ;
	addrServ.sin_family = AF_INET;
	addrServ.sin_port = htons(DEFAULT_PORT);
	addrServ.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	iResult = bind(SeverSocket, (const struct sockaddr*)&addrServ,sizeof(SOCKADDR_IN));
	if(iResult == SOCKET_ERROR)
	{
		//Bind failed!
		closesocket(SeverSocket);
		WSACleanup();
		return 1;
	}
	iResult = listen(SeverSocket,SOMAXCONN);
	if(iResult == SOCKET_ERROR)
	{
		//Listen failed!
		closesocket(SeverSocket);
		WSACleanup();
		return -1;
	}
	//Tcp sever strting...
	WSAEVENT Event = WSACreateEvent();
	int iIndex = 0,i;
	int iEventTotal = 0;
	WSAEVENT eventArray[WSA_MAXIMUM_WAIT_EVENTS];
	SOCKET sockArray[WSA_MAXIMUM_WAIT_EVENTS];
	WSAEventSelect(SeverSocket,Event,FD_ACCEPT);
	eventArray[iEventTotal] = Event;
	sockArray[iEventTotal] = SeverSocket;
	iEventTotal++;
	//处理网络事件
	SOCKADDR_IN addrClient;
	int addrClientlen = sizeof(SOCKADDR_IN);
	char recvbuf[DEFAULT_BUFLEN] ;
	int recvbuflen = DEFAULT_BUFLEN;
	while(1)
	{
		//在所有时间对象上等待
		iIndex = WSAWaitForMultipleEvents(iEventTotal, eventArray,FALSE, WSA_INFINITE,FALSE);
		iIndex = iIndex - WSA_WAIT_EVENT_0;
		for(i=iIndex; i<iEventTotal;i++)
		{
			iResult = WSAWaitForMultipleEvents(1, &eventArray[i],TRUE,1000,FALSE);
			if(iResult =WSA_WAIT_FAILED || iResult == WSA_WAIT_TIMEOUT)
			{
				continue;
			}
			else
			{
				WSANETWORKEVENTS newevent;
				WSAEnumNetworkEvents(sockArray[i],eventArray[i],&newevent);
				if(newevent.lNetworkEvents & FD_ACCEPT)		//handle FD_ACCEPT message
				{
					if(newevent.iErrorCode[FD_ACCEPT_BIT]==0)
					{
						if(iEventTotal>WSA_MAXIMUM_WAIT_EVENTS)
						{
							//too many link,ignore....
							continue;
						}
						SOCKET AcceptSocket = accept(sockArray[i],(SOCKADDR FAR*)&addrClient,&addrClientlen);
						//"接收到新的连接"
						WSAEVENT newEvent1 = WSACreateEvent();
						WSAEventSelect(AcceptSocket, newEvent1,FD_READ|FD_CLOSE|FD_WRITE);
						eventArray[iEventTotal] = newEvent1;
						sockArray[iEventTotal] = AcceptSocket;
						iEventTotal++;
					}
				}
				if(newevent.lNetworkEvents & FD_READ)
				{
					if(newevent.iErrorCode[FD_READ_BIT]==0)
					{
						//if data reach
						memset(recvbuf,0,recvbuflen);
						iResult = recv(sockArray[i],recvbuf,recvbuflen,0);
						if(iResult>0)
						{
							//seccess, deal with the data
						}
						else
						{
							//recv failed
							<span style="font-family: Arial, Helvetica, sans-serif;">closesocket(sockArray[i]);</span>
<span style="font-family: Arial, Helvetica, sans-serif;"></span>
						}
					}
				}
				if(newevent.lNetworkEvents & FD_CLOSE)
				{
					//closing currect connection
					closesocket(sockArray[i]);
				}
				if(newevent.lNetworkEvents & FD_WRITE)
				{
					//do data send
				}
			}
		}
		 
	}
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值