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

📄 socketimpl.cpp

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//// SocketImpl.cpp//// $Id: //poco/1.2/Net/src/SocketImpl.cpp#2 $//// Library: Net// Package: Sockets// Module:  SocketImpl//// Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/Net/SocketImpl.h"#include "Poco/Net/NetException.h"#include "Poco/Net/StreamSocketImpl.h"#include "Poco/NumberFormatter.h"#include "Poco/Timestamp.h"#include <string.h>using Poco::IOException;using Poco::TimeoutException;using Poco::InvalidArgumentException;using Poco::NumberFormatter;using Poco::Timespan;namespace Poco {namespace Net {SocketImpl::SocketImpl():	_sockfd(POCO_INVALID_SOCKET){}SocketImpl::SocketImpl(poco_socket_t sockfd):	_sockfd(sockfd){}SocketImpl::~SocketImpl(){	close();}	SocketImpl* SocketImpl::acceptConnection(SocketAddress& clientAddr){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	char buffer[SocketAddress::MAX_ADDRESS_LENGTH];	struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(buffer);	poco_socklen_t saLen = sizeof(buffer);	poco_socket_t sd;	do	{		sd = ::accept(_sockfd, pSA, &saLen);	}	while (sd == POCO_INVALID_SOCKET && lastError() == POCO_EINTR);	if (sd != POCO_INVALID_SOCKET)	{		clientAddr = SocketAddress(pSA, saLen);		return new StreamSocketImpl(sd);	}	error(); // will throw	return 0;}void SocketImpl::connect(const SocketAddress& address){	if (_sockfd == POCO_INVALID_SOCKET)	{		init(address.af());	}	int rc;	do	{		rc = ::connect(_sockfd, address.addr(), address.length());	}	while (rc != 0 && lastError() == POCO_EINTR);	if (rc != 0) error(address.toString());}void SocketImpl::connect(const SocketAddress& address, const Poco::Timespan& timeout){	poco_assert (_sockfd == POCO_INVALID_SOCKET);		init(address.af());	setBlocking(false);	try	{		int rc = ::connect(_sockfd, address.addr(), address.length());		if (rc != 0)		{			if (lastError() != POCO_EINPROGRESS && lastError() != POCO_EWOULDBLOCK)				error(address.toString());			if (!poll(timeout, SELECT_READ | SELECT_WRITE))				throw Poco::TimeoutException("connect timed out", address.toString());			int err = socketError();			if (err != 0) error(err);		}	}	catch (Poco::Exception&)	{		setBlocking(true);		throw;	}	setBlocking(true);}void SocketImpl::connectNB(const SocketAddress& address){	if (_sockfd == POCO_INVALID_SOCKET)	{		init(address.af());	}	setBlocking(false);	int rc = ::connect(_sockfd, address.addr(), address.length());	if (rc != 0)	{		if (lastError() != POCO_EINPROGRESS && lastError() != POCO_EWOULDBLOCK)			error(address.toString());	}}void SocketImpl::bind(const SocketAddress& address, bool reuseAddress){	if (_sockfd == POCO_INVALID_SOCKET)	{		init(address.af());	}	if (reuseAddress)	{		setReuseAddress(true);		setReusePort(true);	}	int rc = ::bind(_sockfd, address.addr(), address.length());	if (rc != 0) error(address.toString());}	void SocketImpl::listen(int backlog){	poco_assert (_sockfd != POCO_INVALID_SOCKET);		int rc = ::listen(_sockfd, backlog);	if (rc != 0) error();}void SocketImpl::close(){	if (_sockfd != POCO_INVALID_SOCKET)	{		poco_closesocket(_sockfd);		_sockfd = POCO_INVALID_SOCKET;	}}void SocketImpl::shutdownReceive(){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	int rc = ::shutdown(_sockfd, 0);	if (rc != 0) error();}	void SocketImpl::shutdownSend(){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	int rc = ::shutdown(_sockfd, 1);	if (rc != 0) error();}	void SocketImpl::shutdown(){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	int rc = ::shutdown(_sockfd, 2);	if (rc != 0) error();}int SocketImpl::sendBytes(const void* buffer, int length, int flags){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	int rc;	do	{		rc = ::send(_sockfd, reinterpret_cast<const char*>(buffer), length, flags);	}	while (rc < 0 && lastError() == POCO_EINTR);	if (rc < 0) error();	return rc;}int SocketImpl::receiveBytes(void* buffer, int length, int flags){	poco_assert (_sockfd != POCO_INVALID_SOCKET);#if defined(POCO_BROKEN_TIMEOUTS)	if (_recvTimeout.totalMicroseconds() != 0)	{		if (!poll(_recvTimeout, SELECT_READ))			throw TimeoutException();	}#endif	int rc;	do	{		rc = ::recv(_sockfd, reinterpret_cast<char*>(buffer), length, flags);	}	while (rc < 0 && lastError() == POCO_EINTR);	if (rc < 0) 	{		if (lastError() == POCO_EAGAIN || lastError() == POCO_ETIMEDOUT)			throw TimeoutException();		else			error();	}	return rc;}int SocketImpl::sendTo(const void* buffer, int length, const SocketAddress& address, int flags){	poco_assert (_sockfd != POCO_INVALID_SOCKET);	int rc;	do	{		rc = ::sendto(_sockfd, reinterpret_cast<const char*>(buffer), length, flags, address.addr(), address.length());	}	while (rc < 0 && lastError() == POCO_EINTR);	if (rc < 0) error();	return rc;}int SocketImpl::receiveFrom(void* buffer, int length, SocketAddress& address, int flags){	poco_assert (_sockfd != POCO_INVALID_SOCKET);#if defined(POCO_BROKEN_TIMEOUTS)	if (_recvTimeout.totalMicroseconds() != 0)	{		if (!poll(_recvTimeout, SELECT_READ))			throw TimeoutException();	}#endif		char abuffer[SocketAddress::MAX_ADDRESS_LENGTH];	struct sockaddr* pSA = reinterpret_cast<struct sockaddr*>(abuffer);	poco_socklen_t saLen = sizeof(abuffer);	int rc;	do	{		rc = ::recvfrom(_sockfd, reinterpret_cast<char*>(buffer), length, flags, pSA, &saLen);	}	while (rc < 0 && lastError() == POCO_EINTR);	if (rc >= 0)	{		address = SocketAddress(pSA, saLen);	}	else	{		if (lastError() == POCO_EAGAIN || lastError() == POCO_ETIMEDOUT)			throw TimeoutException();		else			error();	}	return rc;}void SocketImpl::sendUrgent(unsigned char data){	int rc = ::send(_sockfd, reinterpret_cast<const char*>(&data), sizeof(data), MSG_OOB);	if (rc < 0) error();}int SocketImpl::available(){	int result;	ioctl(FIONREAD, result);	return result;}bool SocketImpl::poll(const Poco::Timespan& timeout, int mode){	fd_set fdRead;	fd_set fdWrite;	fd_set fdExcept;	FD_ZERO(&fdRead);	FD_ZERO(&fdWrite);	FD_ZERO(&fdExcept);	if (mode & SELECT_READ)	{		FD_SET(_sockfd, &fdRead);	}	if (mode & SELECT_WRITE)	{		FD_SET(_sockfd, &fdWrite);	}	if (mode & SELECT_ERROR)	{		FD_SET(_sockfd, &fdExcept);	}	Poco::Timespan remainingTime(timeout);	int rc;	do	{		struct timeval tv;		tv.tv_sec  = (long) remainingTime.totalSeconds();		tv.tv_usec = (long) remainingTime.useconds();		Poco::Timestamp start;		rc = ::select(int(_sockfd) + 1, &fdRead, &fdWrite, &fdExcept, &tv);		if (rc < 0 && lastError() == POCO_EINTR)		{			Poco::Timestamp end;			Poco::Timespan waited = end - start;			if (waited > remainingTime)				remainingTime -= waited;			else				remainingTime = 0;		}	}	while (rc < 0 && lastError() == POCO_EINTR);	if (rc < 0) error();	return rc > 0; }	void SocketImpl::setSendBufferSize(int size){	setOption(SOL_SOCKET, SO_SNDBUF, size);}	int SocketImpl::getSendBufferSize(){	int result;	getOption(SOL_SOCKET, SO_SNDBUF, result);	return result;}void SocketImpl::setReceiveBufferSize(int size){	setOption(SOL_SOCKET, SO_RCVBUF, size);}	int SocketImpl::getReceiveBufferSize(){	int result;	getOption(SOL_SOCKET, SO_RCVBUF, result);	return result;}void SocketImpl::setSendTimeout(const Poco::Timespan& timeout){#if defined(_WIN32)	int value = (int) timeout.totalMilliseconds();	setOption(SOL_SOCKET, SO_SNDTIMEO, value);#else	setOption(SOL_SOCKET, SO_SNDTIMEO, timeout);#endif}Poco::Timespan SocketImpl::getSendTimeout(){	Timespan result;#if defined(_WIN32)	int value;	getOption(SOL_SOCKET, SO_SNDTIMEO, value);	result = Timespan::TimeDiff(value)*1000;#else	getOption(SOL_SOCKET, SO_SNDTIMEO, result);#endif	return result;}void SocketImpl::setReceiveTimeout(const Poco::Timespan& timeout){#if defined(_WIN32)	int value = (int) timeout.totalMilliseconds();	setOption(SOL_SOCKET, SO_RCVTIMEO, value);#else	setOption(SOL_SOCKET, SO_RCVTIMEO, timeout);

⌨️ 快捷键说明

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