通讯端点定义类:
#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;
}