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

📄 socketport.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Copyright (C) 1999-2005 Open Source Telecom Corporation.//  // This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.// // This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.// // As a special exception, you may use this file as part of a free software// library without restriction.  Specifically, if other files instantiate// templates or use macros or inline functions from this file, or you compile// this file and link it with other files to produce an executable, this// file does not by itself cause the resulting executable to be covered by// the GNU General Public License.  This exception does not however    // invalidate any other reasons why the executable file might be covered by// the GNU General Public License.    //// This exception applies only to the code released under the name GNU// Common C++.  If you copy code from other releases into a copy of GNU// Common C++, as the General Public License permits, the exception does// not apply to the code that you add in this way.  To avoid misleading// anyone as to the status of such modified files, you must delete// this exception notice from them.//// If you write modifications of your own for GNU Common C++, it is your choice// whether to permit this exception to apply to your modifications.// If you do not wish that, delete this exception notice.//#include <cc++/config.h>#include <cc++/thread.h>#include <cc++/address.h>#include <cc++/socket.h>#include <cc++/export.h>#include <cc++/socketport.h>#include "private.h"#ifndef WIN32#include <cerrno>#define socket_errno errno#else#define socket_errno WSAGetLastError()#endif#ifndef	INADDR_LOOPBACK#define	INADDR_LOOPBACK	(unsigned long)0x7f000001#endif#ifdef	CCXX_NAMESPACESnamespace ost {#endifSocketPort::SocketPort(SocketService *svc, TCPSocket &tcp) :Socket(accept(tcp.getSocket(), NULL, NULL)){	detect_pending = true;	detect_output = false;	detect_disconnect = true;#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	next = prev = NULL;	service = NULL;	// FIXME: use macro here and in other files...#ifndef WIN32	if(so > -1)#else	if(so != INVALID_SOCKET)#endif	{		setError(false);    if( svc )  		svc->attach(this);	}}#ifdef  CCXX_IPV6SocketPort::SocketPort(SocketService *svc, TCPV6Socket &tcp) :Socket(accept(tcp.getSocket(), NULL, NULL)){	detect_pending = true;	detect_output = false;	detect_disconnect = true;#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	next = prev = NULL;	service = NULL;	// FIXME: use macro here and in other files...#ifndef WIN32	if(so > -1)#else	if(so != INVALID_SOCKET)#endif	{		setError(false);    if( svc )  		svc->attach(this);	}}#endifSocketPort::SocketPort(SocketService *svc, const IPV4Address &ia, tpport_t port) :Socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP){#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	struct sockaddr_in addr;	memset(&addr, 0, sizeof(addr));	next = prev = NULL;	service = NULL;	addr.sin_family = AF_INET;	addr.sin_addr = getaddress(ia);	addr.sin_port = htons(port);	detect_pending = true;	detect_output = false;	detect_disconnect = true;	if(bind(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)))	{		endSocket();		error(errBindingFailed,"Could not bind socket",socket_errno);		return;	}	state = BOUND;	setError(false);  if(svc)  	svc->attach(this);}#ifdef  CCXX_IPV6SocketPort::SocketPort(SocketService *svc, const IPV6Address &ia, tpport_t port) :Socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP){#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	struct sockaddr_in6 addr;	memset(&addr, 0, sizeof(addr));	next = prev = NULL;	service = NULL;	addr.sin6_family = AF_INET6;	addr.sin6_addr = getaddress(ia);	addr.sin6_port = htons(port);	detect_pending = true;	detect_output = false;	detect_disconnect = true;	if(bind(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)))	{		endSocket();		error(errBindingFailed,"Could not bind socket",socket_errno);		return;	}	state = BOUND;	setError(false);  if(svc)  	svc->attach(this);}#endifSocketPort::SocketPort(SocketService *svc, const IPV4Host &ih, tpport_t port) :Socket(AF_INET, SOCK_STREAM, IPPROTO_TCP){#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	struct sockaddr_in addr;	memset(&addr, 0, sizeof(addr));	next = prev = NULL;	service = NULL;	addr.sin_family = AF_INET;	addr.sin_addr = getaddress(ih);	addr.sin_port = htons(port);	detect_pending = true;	detect_disconnect = true;#ifndef WIN32	long opts = fcntl(so, F_GETFL);	fcntl(so, F_SETFL, opts | O_NDELAY);#else	u_long opts = 1;	ioctlsocket(so,FIONBIO,&opts);#endif	int rtn = ::connect(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr));	if(!rtn)	{		state = CONNECTED;	}	else	{#ifndef WIN32		if(errno == EINPROGRESS)#else		if(WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK)#endif		{			state = CONNECTING;		}		else		{			endSocket();			connectError();			return;		}	}#ifndef WIN32	fcntl(so, F_SETFL, opts);#else	opts = 0;	ioctlsocket(so,FIONBIO,&opts);#endif	setError(false);	detect_output = (state == CONNECTING);	if(svc)  		svc->attach(this);//	if(state == CONNECTING)//		setDetectOutput(true);}#ifdef  CCXX_IPV6SocketPort::SocketPort(SocketService *svc, const IPV6Host &ih, tpport_t port) :Socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP){#ifdef WIN32	// FIXME: error handling	event = CreateEvent(NULL,TRUE,FALSE,NULL);#endif	struct sockaddr_in6 addr;	memset(&addr, 0, sizeof(addr));	next = prev = NULL;	service = NULL;	addr.sin6_family = AF_INET6;	addr.sin6_addr = getaddress(ih);	addr.sin6_port = htons(port);	detect_pending = true;	detect_disconnect = true;#ifndef WIN32	long opts = fcntl(so, F_GETFL);	fcntl(so, F_SETFL, opts | O_NDELAY);#else	u_long opts = 1;	ioctlsocket(so,FIONBIO,&opts);#endif	int rtn = ::connect(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr));	if(!rtn)	{		state = CONNECTED;	}	else	{#ifndef WIN32		if(errno == EINPROGRESS)#else		if(WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK)#endif		{			state = CONNECTING;		}		else		{			endSocket();			connectError();			return;		}	}#ifndef WIN32	fcntl(so, F_SETFL, opts);#else	opts = 0;	ioctlsocket(so,FIONBIO,&opts);#endif	setError(false);	detect_output = (state == CONNECTING);	if(svc)  		svc->attach(this);//	if(state == CONNECTING)//		setDetectOutput(true);}#endifSocketPort::~SocketPort(){#ifdef WIN32	CloseHandle(event);#endif	if(service) {		service->detach(this);	}	endSocket();}void SocketPort::expired(void){}void SocketPort::pending(void){}void SocketPort::output(void){}void SocketPort::disconnect(void){}void SocketPort::attach( SocketService* svc ){	if(service)		service->detach(this);	service = svc;		if(svc)		svc->attach(this);}Socket::Error SocketPort::connect(const IPV4Address &ia, tpport_t port){	struct sockaddr_in addr;	Error rtn = errSuccess;	memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_addr = getaddress(ia);	addr.sin_port = htons(port);#ifndef WIN32	long opts = fcntl(so, F_GETFL);	fcntl(so, F_SETFL, opts | O_NDELAY);#else	u_long opts = 1;	ioctlsocket(so,FIONBIO,&opts);#endif	// Win32 will crash if you try to connect to INADDR_ANY.	if ( INADDR_ANY == addr.sin_addr.s_addr )	        addr.sin_addr.s_addr = INADDR_LOOPBACK;	if(::connect(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)))		rtn = connectError();#ifndef WIN32	fcntl(so, F_SETFL, opts);#else	opts = 0;	ioctlsocket(so,FIONBIO,&opts);#endif	return rtn;}#ifdef  CCXX_IPV6Socket::Error SocketPort::connect(const IPV6Address &ia, tpport_t port){	struct sockaddr_in6 addr;	Error rtn = errSuccess;	memset(&addr, 0, sizeof(addr));	addr.sin6_family = AF_INET6;	addr.sin6_addr = getaddress(ia);	addr.sin6_port = htons(port);#ifndef WIN32	long opts = fcntl(so, F_GETFL);	fcntl(so, F_SETFL, opts | O_NDELAY);#else	u_long opts = 1;	ioctlsocket(so,FIONBIO,&opts);#endif	// Win32 will crash if you try to connect to INADDR_ANY.	if(!memcmp(&addr.sin6_addr, &in6addr_any, sizeof(in6addr_any)))		memcpy(&addr.sin6_addr, &in6addr_loopback, sizeof(in6addr_loopback));	if(::connect(so, (struct sockaddr *)&addr, (socklen_t)sizeof(addr)))		rtn = connectError();#ifndef WIN32	fcntl(so, F_SETFL, opts);#else	opts = 0;	ioctlsocket(so,FIONBIO,&opts);#endif	return rtn;}#endifvoid SocketPort::setTimer(timeout_t ptimer){	TimerPort::setTimer(ptimer);  if( service )  	service->update();}void SocketPort::incTimer(timeout_t ptimer){	TimerPort::incTimer(ptimer);  if( service )  	service->update();}void SocketPort::setDetectPending( bool val ){	if ( detect_pending != val ) {		detect_pending = val;#ifdef USE_POLL		if ( ufd ) {			if ( val ) {				ufd->events |= POLLIN;			} else {				ufd->events &= ~POLLIN;			}		}#endif    if( service )  		service->update();	}}void SocketPort::setDetectOutput( bool val ){	if ( detect_output != val ) {		detect_output = val;#ifdef USE_POLL		if ( ufd ) {			if ( val ) {				ufd->events |= POLLOUT;			} else {				ufd->events &= ~POLLOUT;			}		}#endif    if( service )  		service->update();	}}#ifdef WIN32class SocketService::Sync{public:	/* FIXME: error handling */	Sync():		sync(CreateEvent(NULL,TRUE,FALSE,NULL)),		semWrite(CreateSemaphore(NULL,1,1,NULL)),		flag(-1)	{ }	~Sync() 	{		CloseHandle(sync);		CloseHandle(semWrite);	}

⌨️ 快捷键说明

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