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

📄 socket.cpp

📁 贡献一份commoncpp2,有兴趣的可以研究一下
💻 CPP
📖 第 1 页 / 共 5 页
字号:
}Socket::Error Socket::setKeepAlive(bool enable){	int opt = (enable ? ~0: 0);#if (defined(SO_KEEPALIVE) || defined(WIN32))	if(setsockopt(so, SOL_SOCKET, SO_KEEPALIVE,		      (char *)&opt, (socklen_t)sizeof(opt)))		return error(errKeepaliveDenied,"Could not set socket keep-alive option",socket_errno);#endif	flags.keepalive = enable;	return errSuccess;}Socket::Error Socket::setLinger(bool linger){#ifdef	SO_LINGER	flags.linger = linger;	return errSuccess;#else	return error(errServiceUnavailable,"Socket lingering not supported");#endif}Socket::Error Socket::setRouting(bool enable){	int opt = (enable ? 1 : 0);#ifdef	SO_DONTROUTE	if(setsockopt(so, SOL_SOCKET, SO_DONTROUTE,		      (char *)&opt, (socklen_t)sizeof(opt)))		return error(errRoutingDenied,"Could not set dont-route socket option",socket_errno);#endif	flags.route = enable;	return errSuccess;}Socket::Error Socket::setNoDelay(bool enable){	int opt = (enable ? 1 : 0);	if(setsockopt(so, IPPROTO_TCP, TCP_NODELAY,		      (char *)&opt, (socklen_t)sizeof(opt)))		return error(errNoDelay,"Could not set tcp-nodelay socket option",socket_errno);	return errSuccess;}Socket::Error Socket::setTypeOfService(Tos service){#ifdef	SOL_IP	unsigned char tos;	switch(service)	{#ifdef 	IPTOS_LOWDELAY	case tosLowDelay:		tos = IPTOS_LOWDELAY;		break;#endif#ifdef 	IPTOS_THROUGHPUT	case tosThroughput:		tos = IPTOS_THROUGHPUT;		break;#endif#ifdef	IPTOS_RELIABILITY	case tosReliability:		tos = IPTOS_RELIABILITY;		break;#endif#ifdef	IPTOS_MINCOST	case tosMinCost:		tos = IPTOS_MINCOST;		break;#endif	default:		return error(errServiceUnavailable,"Unknown type-of-service");	}	if(setsockopt(so, SOL_IP, IP_TOS,(char *)&tos, (socklen_t)sizeof(tos)))		return error(errServiceDenied,"Could not set type-of-service",socket_errno);	return errSuccess;#else	return error(errServiceUnavailable,"Socket type-of-service not supported",socket_errno);#endif}Socket::Error Socket::setTimeToLiveByFamily(unsigned char ttl, Family fam){	if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	switch(fam)	{#ifdef	CCXX_IPV6	case IPV6:		flags.ttl = ttl;		setsockopt(so, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,	sizeof(ttl));		return errSuccess;#endif	default:#ifdef	IP_MULTICAST_TTL		flags.ttl = ttl;		setsockopt(so, IPPROTO_IP, IP_MULTICAST_TTL, (char *)&ttl, sizeof(ttl));		return errSuccess;#else		return error(errServiceUnavailable,"Multicast not supported");#endif	}}Socket::Error Socket::setLoopbackByFamily(bool enable, Family family){	unsigned char loop;		if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	if(enable)		loop = 1;	else		loop = 0;	flags.loopback = enable;		switch(family)	{#ifdef	CCXX_IPV6	case IPV6:		setsockopt(so, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (char *)&loop, sizeof(loop));		return errSuccess;#endif	default:	#ifdef  IP_MULTICAST_LOOP		setsockopt(so, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loop, sizeof(loop));		return errSuccess;#else		return error(errServiceUnavailable,"Multicast not supported");#endif	}}bool Socket::isPending(Pending pending, timeout_t timeout){	int status;#ifdef USE_POLL	struct pollfd pfd;	pfd.fd = so;	pfd.revents = 0;	if(so == INVALID_SOCKET)		return true;	switch(pending)	{	case pendingInput:		pfd.events = POLLIN;		break;	case pendingOutput:		pfd.events = POLLOUT;		break;	case pendingError:		pfd.events = POLLERR | POLLHUP;		break;	}	status = 0;	while(status < 1)	{		if(timeout == TIMEOUT_INF)			status = poll(&pfd, 1, -1);		else			status = poll(&pfd, 1, timeout);		if(status < 1)		{			// don't stop polling because of a simple			// signal :)			if(status == -1 && errno == EINTR)				continue;			return false;		}	}	if(pfd.revents & pfd.events)		return true;	return false;#else	struct timeval tv;	struct timeval *tvp = &tv;	fd_set grp;	if(timeout == TIMEOUT_INF)		tvp = NULL;	else	{		tv.tv_usec = (timeout % 1000) * 1000;		tv.tv_sec = timeout / 1000;	}	FD_ZERO(&grp);	SOCKET sosave = so;	if(so == INVALID_SOCKET)		return true;	FD_SET(sosave, &grp);#ifdef	WIN32	Thread::Cancel cancel = Thread::enterCancel();#endif	switch(pending)	{	case pendingInput:		status = select((int)so + 1, &grp, NULL, NULL, tvp);		break;	case pendingOutput:		status = select((int)so + 1, NULL, &grp, NULL, tvp);		break;	case pendingError:		status = select((int)so + 1, NULL, NULL, &grp, tvp);		break;	}#ifdef	WIN32	Thread::exitCancel(cancel);#endif	if(status < 1)		return false;	if(FD_ISSET(so, &grp))		return true;	return false;#endif}Socket &Socket::operator=(const Socket &from){	if(so == from.so)		return *this;	if(state != INITIAL)		endSocket();	so = DUP_SOCK(from.so,from.state);	if(so == INVALID_SOCKET)	{		error(errCopyFailed,"Could not duplicate socket handle",socket_errno);		state = INITIAL;	}	else		state = from.state;	return *this;}void Socket::setCompletion(bool immediate){	flags.completion = immediate;#ifdef WIN32	unsigned long flag;	// note that this will not work on some versions of Windows for Workgroups. Tough. -- jfc	switch( immediate )	{	case false:		// this will not work if you are using WSAAsyncSelect or WSAEventSelect.		// -- perhaps I should throw an exception		flag = 1;//		ioctlsocket( so, FIONBIO, (unsigned long *) 1);		break;	case true:		flag = 0;//		ioctlsocket( so, FIONBIO, (unsigned long *) 0);		break;	}	ioctlsocket(so, FIONBIO, &flag);#else	int fflags = fcntl(so, F_GETFL);	switch( immediate )	{	case false:		fflags |= O_NONBLOCK;		fcntl(so, F_SETFL, fflags);		break;	case true:		fflags &=~ O_NONBLOCK;		fcntl(so, F_SETFL, fflags);		break;	}#endif}IPV4Host Socket::getIPV4Sender(tpport_t *port) const{	struct sockaddr_in from;	char buf;	socklen_t len = sizeof(from);	int rc = ::recvfrom(so, &buf, 1, MSG_PEEK,			    (struct sockaddr *)&from, &len);#ifdef WIN32	if(rc < 1 && WSAGetLastError() != WSAEMSGSIZE)	{		if(port)			*port = 0;		memset((void*) &from, 0, sizeof(from));		error(errInput,"Could not read from socket",socket_errno);	}#else	if(rc < 1)	{		if(port)			*port = 0;		memset((void*) &from, 0, sizeof(from));		error(errInput,"Could not read from socket",socket_errno);	}#endif	else	{		if(port)			*port = ntohs(from.sin_port);	}	return IPV4Host(from.sin_addr);}#ifdef  CCXX_IPV6IPV6Host Socket::getIPV6Sender(tpport_t *port) const{	struct sockaddr_in6 from;	char buf;	socklen_t len = sizeof(from);	int rc = ::recvfrom(so, &buf, 1, MSG_PEEK,			    (struct sockaddr *)&from, &len);#ifdef WIN32	if(rc < 1 && WSAGetLastError() != WSAEMSGSIZE)	{		if(port)			*port = 0;		memset((void*) &from, 0, sizeof(from));		error(errInput,"Could not read from socket",socket_errno);	}#else	if(rc < 1)	{		if(port)			*port = 0;		memset((void*) &from, 0, sizeof(from));		error(errInput,"Could not read from socket",socket_errno);	}#endif	else	{		if(port)			*port = ntohs(from.sin6_port);	}	return IPV6Host(from.sin6_addr);}#endifIPV4Host Socket::getIPV4Local(tpport_t *port) const{	struct sockaddr_in addr;	socklen_t len = sizeof(addr);	if(getsockname(so, (struct sockaddr *)&addr, &len))	{		error(errResourceFailure,"Could not get socket address",socket_errno);	      	if(port)			*port = 0;		memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));	}	else	{		if(port)		    	*port = ntohs(addr.sin_port);	}	return IPV4Host(addr.sin_addr);}#ifdef  CCXX_IPV6IPV6Host Socket::getIPV6Local(tpport_t *port) const{	struct sockaddr_in6 addr;	socklen_t len = sizeof(addr);	if(getsockname(so, (struct sockaddr *)&addr, &len))	{		error(errResourceFailure,"Could not get socket address",socket_errno);	      	if(port)			*port = 0;		memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr));	}	else	{		if(port)		    	*port = ntohs(addr.sin6_port);	}	return IPV6Host(addr.sin6_addr);}#endifIPV4Host Socket::getIPV4NAT(tpport_t *port) const{	struct sockaddr_in addr;	socklen_t len = sizeof(addr);	natResult res;	if((res=natv4Lookup((int)so, &addr))!=natOK)	{	  	if(res==natNotSupported)		  	error( errServiceUnavailable, natErrorString( res ) );		else if(res==natSearchErr)		  	error( errSearchErr, natErrorString( res ) );		else		  	error( errLookupFail, natErrorString( res ), socket_errno );		if(port)			*port = 0;		memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));	}	else	{		if(port)	    		*port = ntohs(addr.sin_port);	}	return IPV4Host(addr.sin_addr);}#ifdef  CCXX_IPV6IPV6Host Socket::getIPV6NAT(tpport_t *port) const{	struct sockaddr_in6 addr;	socklen_t len = sizeof(addr);	natResult res;	if((res=natv6Lookup(so, &addr))!=natOK)	{	  	if(res==natNotSupported)		  	error( errServiceUnavailable, natErrorString( res ) );		else if(res==natSearchErr)		  	error( errSearchErr, natErrorString( res ) );		else		  	error( errLookupFail, natErrorString( res ), socket_errno );		if(port)			*port = 0;		memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr));	}	else	{		if(port)	    		*port = ntohs(addr.sin6_port);	}	return IPV6Host(addr.sin6_addr);}#endifIPV4Host Socket::getIPV4Peer(tpport_t *port) const{	struct sockaddr_in addr;	socklen_t len = sizeof(addr);	if(getpeername(so, (struct sockaddr *)&addr, &len))	{#ifndef WIN32		if(errno == ENOTCONN)			error(errNotConnected,"Could not get peer address",socket_errno);		else#endif			error(errResourceFailure,"Could not get peer address",socket_errno);		if(port)			*port = 0;		memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));	}	else	{		if(port)	    		*port = ntohs(addr.sin_port);	}	return IPV4Host(addr.sin_addr);}#ifdef  CCXX_IPV6IPV6Host Socket::getIPV6Peer(tpport_t *port) const{	struct sockaddr_in6 addr;	socklen_t len = sizeof(addr);	if(getpeername(so, (struct sockaddr *)&addr, &len))	{#ifndef WIN32		if(errno == ENOTCONN)			error(errNotConnected,"Could not get peer address",socket_errno);		else#endif			error(errResourceFailure,"Could not get peer address",socket_errno);		if(port)			*port = 0;		memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr));	}	else	{		if(port)	    		*port = ntohs(addr.sin6_port);	}	return IPV6Host(addr.sin6_addr);}#endifSocket::Error Socket::setMulticastByFamily(bool enable, Family family){	socklen_t len;	switch(family)	{#ifdef	CCXX_IPV6	case IPV6:		struct sockaddr_in6 addr;		len = sizeof(addr);		if(enable == flags.multicast)			return errSuccess;		flags.multicast = enable;		if(enable)			getsockname(so, (struct sockaddr *)&addr, &len);		else			memset(&addr.sin6_addr, 0, sizeof(addr.sin6_addr));		setsockopt(so, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&addr.sin6_addr, sizeof(addr.sin6_addr));		return errSuccess;#endif	default:#ifdef	IP_MULTICAST_IF		struct sockaddr_in addr4;		len = sizeof(addr4);		if(enable == flags.multicast)			return errSuccess;		flags.multicast = enable;		if(enable)			getsockname(so, (struct sockaddr *)&addr4, &len);		else			memset(&addr4.sin_addr, 0, sizeof(addr4.sin_addr));		setsockopt(so, IPPROTO_IP, IP_MULTICAST_IF, (char *)&addr4.sin_addr, sizeof(addr4.sin_addr));		return errSuccess;#else		return error(errServiceUnavailable,"Multicast not supported");#endif	}}Socket::Error Socket::join(const IPV4Multicast &ia){#ifdef	IP_ADD_MEMBERSHIP	struct ip_mreq group;	struct sockaddr_in myaddr;	socklen_t len = sizeof(myaddr);	if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	getsockname(so, (struct sockaddr *)&myaddr, &len);	memcpy(&group.imr_interface, &myaddr.sin_addr, sizeof(&myaddr.sin_addr));	group.imr_multiaddr = getaddress(ia);	setsockopt(so, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group, sizeof(group));	return errSuccess;#else	return error(errServiceUnavailable,"Multicast not supported");#endif}#ifdef  CCXX_IPV6Socket::Error Socket::join(const IPV6Multicast &ia){#ifdef	IPV6_ADD_MEMBERSHIP	struct ipv6_mreq group;	struct sockaddr_in6 myaddr;	socklen_t len = sizeof(myaddr);	if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	getsockname(so, (struct sockaddr *)&myaddr, &len);	memcpy(&group.ipv6mr_interface, &myaddr.sin6_addr, sizeof(&myaddr.sin6_addr));	group.ipv6mr_multiaddr = getaddress(ia);	setsockopt(so, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&group, sizeof(group));	return errSuccess;#else	return error(errServiceUnavailable,"Multicast not supported");#endif}#endifSocket::Error Socket::drop(const IPV4Multicast &ia){#ifdef	IP_DROP_MEMBERSHIP	struct ip_mreq group;	struct sockaddr_in myaddr;	socklen_t len = sizeof(myaddr);	if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	getsockname(so, (struct sockaddr *)&myaddr, &len);	memcpy(&group.imr_interface, &myaddr.sin_addr, sizeof(&myaddr.sin_addr));	group.imr_multiaddr = getaddress(ia);	setsockopt(so, IPPROTO_IP, IP_DROP_MEMBERSHIP, (char *)&group, sizeof(group));	return errSuccess;#else	return error(errServiceUnavailable,"Multicast not supported");#endif}#ifdef  CCXX_IPV6Socket::Error Socket::drop(const IPV6Multicast &ia){#ifdef	IPV6_DROP_MEMBERSHIP	struct ipv6_mreq group;	struct sockaddr_in6 myaddr;	socklen_t len = sizeof(myaddr);	if(!flags.multicast)		return error(errMulticastDisabled,"Multicast not enabled on socket");	getsockname(so, (struct sockaddr *)&myaddr, &len);	memcpy(&group.ipv6mr_interface, &myaddr.sin6_addr, sizeof(&myaddr.sin6_addr));	group.ipv6mr_multiaddr = getaddress(ia);	setsockopt(so, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, (char *)&group, sizeof(group));	return errSuccess;#else

⌨️ 快捷键说明

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