通讯端点定义类:
#pragma once #include <WinSock2.h> #define SERVER 1 #define CLIENT 2 #include <iostream> using namespace std; class CEndpoint { public: CEndpoint(void); CEndpoint(SOCKET socket, unsigned int type); CEndpoint(const CEndpoint &endpoint); ~CEndpoint(void); private: SOCKET m_socket; unsigned int m_type; public: SOCKET getsocket(); unsigned char gettype(); bool operator < (const CEndpoint& endpoint) const; friend ostream & operator << (ostream& out, const CEndpoint& endpoint) { out << "socket=" << endpoint.m_socket << " type=" << endpoint.m_type; return out; } }; #include "StdAfx.h" #include "Endpoint.h" CEndpoint::CEndpoint(void) { } CEndpoint::CEndpoint(SOCKET socket, unsigned int type) { m_socket = socket; m_type = type; } CEndpoint::CEndpoint(const CEndpoint &endpoint) { m_socket = endpoint.m_socket; m_type = endpoint.m_type; } CEndpoint::~CEndpoint(void) { } SOCKET CEndpoint::getsocket() { return m_socket; } unsigned char CEndpoint::gettype() { return m_type; } bool CEndpoint::operator<(const CEndpoint& endpoint) const { if (m_socket < endpoint.m_socket) { return true; } else if(m_socket == endpoint.m_socket && m_type < endpoint.m_type) { return true; } return false; }
通讯端点管理类:CEndpointset
#pragma once #include "Endpoint.h" #include <set> using namespace std; typedef set<CEndpoint> EPSET; typedef EPSET::iterator ITERATOR; class CEndpointset { public: CEndpointset(void); ~CEndpointset(void); private: EPSET m_using_epset; EPSET m_connection_epset; EPSET m_disconnection_epset; ITERATOR m_using_li; public: bool insertusing(CEndpoint ep); bool insertconnection(CEndpoint ep); bool insertdisconnection(CEndpoint ep); void gofirstusing(); bool getnextusing(CEndpoint &ep); void display(); void resettle(fd_set* fdread, unsigned int* maxfd); void reset(fd_set* fdread, unsigned int* maxfd); }; #include "StdAfx.h" #include "Endpointset.h" #include <algorithm> #include <iostream> #include <iterator> CEndpointset::CEndpointset(void) { } CEndpointset::~CEndpointset(void) { } bool CEndpointset::insertusing(CEndpoint ep) { pair<set<CEndpoint>::iterator, bool> Insert_Pair; Insert_Pair = m_using_epset.insert(ep); return Insert_Pair.second; } bool CEndpointset::insertconnection(CEndpoint ep) { pair<set<CEndpoint>::iterator, bool> Insert_Pair; Insert_Pair =m_connection_epset.insert(ep); return Insert_Pair.second; } bool CEndpointset::insertdisconnection(CEndpoint ep) { pair<set<CEndpoint>::iterator, bool> Insert_Pair; Insert_Pair = m_disconnection_epset.insert(ep); return Insert_Pair.second; } void CEndpointset::resettle(fd_set* fdread, unsigned int* maxfd) { EPSET myset; set_union(m_using_epset.begin(), m_using_epset.end(), m_connection_epset.begin(), m_connection_epset.end(), inserter(myset, myset.begin())); m_using_epset.clear(); m_using_epset = myset; myset.clear(); set_difference(m_using_epset.begin(), m_using_epset.end(), m_disconnection_epset.begin(), m_disconnection_epset.end(), inserter(myset, myset.begin())); m_using_epset.clear(); m_using_epset = myset; reset(fdread, maxfd); m_connection_epset.clear(); m_disconnection_epset.clear(); } void CEndpointset::gofirstusing() { m_using_li = m_using_epset.begin(); } bool CEndpointset::getnextusing(CEndpoint &ep) { if(m_using_li != m_using_epset.end()) { ep = (*m_using_li); m_using_li++; return true; } return false; } void CEndpointset::display() { copy(m_using_epset.begin(), m_using_epset.end(), ostream_iterator<CEndpoint>(cout, "\n")); } void CEndpointset::reset(fd_set* fdread, unsigned int* maxfd) { FD_ZERO(fdread); ITERATOR LI; for(LI = m_using_epset.begin(); LI != m_using_epset.end(); LI++) { CEndpoint ep = (*LI); if (ep.getsocket() > *maxfd) { *maxfd = ep.getsocket(); } FD_SET(ep.getsocket(), fdread); } }
主函数
// select.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "Endpointset.h" int _tmain(int argc, _TCHAR* argv[]) { WSADATA wsaData; WSAStartup(0x0202, &wsaData); SOCKET sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int ul = 1; ioctlsocket(sListen, FIONBIO,(unsigned long *)&ul); //Bind SOCKADDR_IN local; local.sin_addr.S_un.S_addr = htonl(INADDR_ANY); local.sin_family = AF_INET; local.sin_port = htons(55555); bind(sListen, (struct sockaddr *)&local, sizeof(SOCKADDR_IN)); // Listen listen(sListen, 1); fd_set fdread; FD_ZERO(&fdread); CEndpointset epset; CEndpoint ep(sListen, SERVER); epset.insertusing(ep); FD_SET(sListen, &fdread); unsigned int maxfd = sListen; while(true) { int ret = select(maxfd + 1, &fdread, NULL, NULL, 0); if (ret > 0) { epset.gofirstusing(); while(epset.getnextusing(ep)) { if (FD_ISSET(ep.getsocket(), &fdread)) { if (ep.gettype() == SERVER) { SOCKADDR_IN client; int len = sizeof(client); SOCKET sClient = accept(sListen, (struct sockaddr *)&client, &len); if (sClient == INVALID_SOCKET) { wprintf(L"accept failed with error: %ld\n", WSAGetLastError()); } ioctlsocket(sClient, FIONBIO, (unsigned long *)&ul); CEndpoint newep(sClient, CLIENT); epset.insertconnection(newep); } else if(ep.gettype() == CLIENT) { char buff[256]; int length = recv(ep.getsocket(), buff, 256, 0); if (length <= 0) { wprintf(L"recv failed with error: %ld\n", WSAGetLastError()); epset.insertdisconnection(ep); } else { printf("length=%d buff=%s\n", length, buff); } } } } epset.resettle(&fdread, &maxfd); printf("socket in using\n"); epset.display(); printf("*********************\n"); printf("socket in fdread\n"); for(int i=0; i<fdread.fd_count; i++) { printf("socket=%d\n", fdread.fd_array[i]); } } } return 0; }