⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skset.cpp

📁 socket的事件分发模型
💻 CPP
字号:
/*
 *	Copyright (c) 2003-2005 Zbchun.
 *	这是一个开源软件,允许任意使用,但必须保留该版权声明。
 */
#include "skset.h"
#include "skfwd.h"
#include "z_errdef.h"
#include <assert.h>
#include <malloc.h>

#if zPLAT_WIN
sockset::sockset(size_t cnt /* = FD_SETSIZE */) : m_size(cnt)
{
	if (cnt > 0){
		m_pset = (fd_set*)malloc(sizeof(u_int)+sizeof(SOCKET)*cnt);
		m_pset->fd_count = 0;
	}else{
		m_pset = 0;
	}
}	

sockset::sockset(const sockset& rhs) 
{
	if (rhs.m_size == 0){
		m_pset = 0;
		m_size = 0;
		return;
	}
	m_pset = (fd_set*)malloc(sizeof(u_int)+sizeof(SOCKET)*rhs.m_size);
	m_size = rhs.m_size;
	m_pset->fd_count = 0;
}

int sockset::count() const								//	set中包括的SOCKET数目
{
	return m_pset->fd_count;
}

void sockset::reset()
{
	if (m_pset){
		m_pset->fd_count = 0;
	}
}	

HRET sockset::create(size_t size)
{
	clear();
	m_pset = (fd_set*)malloc(sizeof(u_int)+sizeof(SOCKET)*size);
	if (!m_pset)
		return -1;
	m_size = size;
	m_pset->fd_count = 0;
	return 0;
}

HRET sockset::add(SOCKET hSocket)
{
	assert(m_pset);
	if (m_pset->fd_count >= m_size)
		return err_overflow;
	assert(!test(hSocket));

	m_pset->fd_array[m_pset->fd_count++] = hSocket;
	return err_noerror;
}

HRET sockset::remove(SOCKET hSocket)
{
	assert(m_pset);
	for(u_int i = 0 ; i < m_pset->fd_count ; ++i)
	{
		if (m_pset->fd_array[i] == hSocket){
			for( ; i < m_pset->fd_count-1 ; ++i)
			{
				m_pset->fd_array[i] = m_pset->fd_array[i+1];
			}
			--m_pset->fd_count;
			return err_noerror;
		}
	}
	return err_notexist;
}

bool sockset::test(SOCKET hSocket) const
{
	assert(m_pset);
	return FD_ISSET(hSocket, m_pset) != 0;
}

int sockset::correct()
{
	assert(m_pset);

	sockaddr_in addr;
	int oldcnt = m_pset->fd_count;
	for(int i = (int)m_pset->fd_count-1 ; i >= 0 ; --i)
	{
		SOCKET hSocket = m_pset->fd_array[i];
		addrlen_t len = sizeof(addr);
		int ret = ::getsockname(hSocket, (sockaddr*)&addr, &len);
		if (ret < 0){					//	这个socket是个无效句柄,将其删除
			DUMP1("error: SOCKET[%d] is a invalid SOCKET,will be remove.\n", hSocket);

			for(u_int j = i+1 ; j < m_pset->fd_count ; ++j)
			{
				m_pset->fd_array[i-1] = m_pset->fd_array[i];
			}
			--m_pset->fd_count;
		}
	}
	return oldcnt-m_pset->fd_count;
}

void sockset::clear()
{
	if (m_pset){
		free(m_pset);
	}
	m_pset = 0;
	m_size = 0;
}

#else	//zPLAT_WIN
//defined(zPLAT_POSIX)
#define SKSET_BITS 32

sockset::sockset(size_t size) : m_cnt(0), m_pset(0), m_size(0)
{
	create(size);
}	

int sockset::count() const
{
	return m_cnt;
}

HRET sockset::create(size_t size)
{
	assert(size % SKSET_BITS == 0);

	clear();	
	if (size > 0){
		m_pset = (fd_set*)calloc(size/8, 1);
		m_size = size;
	}else{
		m_size = 0;
		m_pset = 0;
	}
	m_cnt = 0;
	return 0;
}

void sockset::reset()
{
	if (m_pset){
		memset(m_pset, 0, m_size/8);
		m_cnt = 0;
	}
}

HRET sockset::add(SOCKET hSocket)
{
	assert(hSocket <= m_size);
	assert(m_pset);
	
	if (FD_ISSET(hSocket, m_pset)){
//		DUMP1("bug: SOCKET[%d] already exist!\n", hSocket);
		return err_overrun;
	}
	FD_SET(hSocket, m_pset);
	++m_cnt;
	return err_noerror;
}

HRET sockset::remove(SOCKET hSocket)
{
	assert(hSocket < m_size);
	assert(m_pset);
	
	if (FD_ISSET(hSocket, m_pset)){
		FD_CLR(hSocket, m_pset);
		--m_cnt;
		return err_noerror;
	}
	return err_notexist;
}

bool sockset::test(SOCKET hSocket) const
{
	assert(m_pset);
	
	return FD_ISSET(hSocket, m_pset) != 0;
}

int sockset::correct()
{
	assert(m_pset);
	
	sockaddr_in addr;
	int oldcnt = m_cnt;
	for(int i = 0 ; i < m_size ; ++i)
	{
		if (FD_ISSET(i, m_pset)){
			addrlen_t len = sizeof(addr);
			int ret = ::getsockname(i, (sockaddr*)&addr, &len);
			if (ret < 0){					//	这个socket是个无效句柄,将其删除
//				DUMP1("error: SOCKET[%d] is a invalid SOCKET, will be remove\n", i);
				FD_CLR(i, m_pset);
				--m_cnt;
			}
		}
	}
	return oldcnt-m_cnt;
}

void sockset::clear()
{
	if (m_pset){
		free(m_pset);
	}
	m_pset = 0;
	m_size = 0;
	m_cnt = 0;
}

#endif //


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -