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

📄 q3socketdevice_unix.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the Qt3Support module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"// Almost always the same. If not, specify in qplatformdefs.h.#if !defined(QT_SOCKOPTLEN_T)# define QT_SOCKOPTLEN_T QT_SOCKLEN_T#endif// Tru64 redefines accept -> _accept with _XOPEN_SOURCE_EXTENDEDstatic inline int qt_socket_accept(int s, struct sockaddr *addr, QT_SOCKLEN_T *addrlen){ return ::accept(s, addr, addrlen); }#if defined(accept)# undef accept#endif// UnixWare 7 redefines listen -> _listenstatic inline int qt_socket_listen(int s, int backlog){ return ::listen(s, backlog); }#if defined(listen)# undef listen#endif// UnixWare 7 redefines socket -> _socketstatic inline int qt_socket_socket(int domain, int type, int protocol){ return ::socket(domain, type, protocol); }#if defined(socket)# undef socket#endif#include "q3socketdevice.h"#ifndef QT_NO_NETWORK#include "qwindowdefs.h"#include <errno.h>#include <sys/types.h>static inline void qt_socket_getportaddr( struct sockaddr *sa,					  Q_UINT16 *port, QHostAddress *addr ){#if !defined(QT_NO_IPV6)    if ( sa->sa_family == AF_INET6 ) {	struct sockaddr_in6 *sa6 = ( struct sockaddr_in6 * )sa;	Q_IPV6ADDR tmp;	memcpy( &tmp, &sa6->sin6_addr.s6_addr, sizeof(tmp) );	QHostAddress a( tmp );	*addr = a;	*port = ntohs( sa6->sin6_port );	return;    }#endif    struct sockaddr_in *sa4 = (struct sockaddr_in *)sa;    QHostAddress a( ntohl( sa4->sin_addr.s_addr ) );    *port = ntohs( sa4->sin_port );    *addr = QHostAddress( ntohl( sa4->sin_addr.s_addr ) );    return;}//#define QSOCKETDEVICE_DEBUG// internalvoid Q3SocketDevice::init(){}Q3SocketDevice::Protocol Q3SocketDevice::getProtocol() const{    if ( isValid() ) {#if !defined (QT_NO_IPV6)	struct sockaddr_storage sa;#else	struct sockaddr sa;#endif	memset( &sa, 0, sizeof(sa) );	QT_SOCKLEN_T sz = sizeof( sa );#if !defined (QT_NO_IPV6)	struct sockaddr *sap = reinterpret_cast<struct sockaddr *>(&sa);	if ( !::getsockname(fd, sap, &sz) ) {	    switch ( sap->sa_family ) {		case AF_INET:		    return IPv4;		case AF_INET6:		    return IPv6;		default:		    return Unknown;	    }	}#else	if ( !::getsockname(fd, &sa, &sz) ) {	    switch ( sa.sa_family ) {		case AF_INET:		    return IPv4;		default:		    return Unknown;	    }	}#endif    }    return Unknown;}/*!    Creates a new socket identifier. Returns -1 if there is a failure    to create the new identifier; error() explains why.    \sa setSocket()*/int Q3SocketDevice::createNewSocket(){#if !defined(QT_NO_IPV6)    int s = qt_socket_socket( protocol() == IPv6 ? AF_INET6 : AF_INET,			      t == Datagram ? SOCK_DGRAM : SOCK_STREAM, 0 );#else    int s = qt_socket_socket( AF_INET, t==Datagram?SOCK_DGRAM:SOCK_STREAM, 0 );#endif    if ( s < 0 ) {	switch( errno ) {	case EPROTONOSUPPORT:	    e = InternalError; // 0 is supposed to work for both types	    break;	case ENFILE:	    e = NoFiles; // special case for this	    break;	case EACCES:	    e = Inaccessible;	    break;	case ENOBUFS:	case ENOMEM:	    e = NoResources;	    break;	case EINVAL:	    e = Impossible;	    break;	default:	    e = UnknownError;	    break;	}    } else {	return s;    }    return -1;}/*!    \reimp    Closes the socket and sets the socket identifier to -1 (invalid).    (This function ignores errors; if there are any then a file    descriptor leakage might result. As far as we know, the only error    that can arise is EBADF, and that would of course not cause    leakage. There may be OS-specific errors that we haven't come    across, however.)    \sa open()*/void Q3SocketDevice::close(){    if ( fd == -1 || !isOpen() )		// already closed	return;    resetStatus();    setOpenMode(NotOpen);    ::close( fd );#if defined(QSOCKETDEVICE_DEBUG)    qDebug( "Q3SocketDevice::close: Closed socket %x", fd );#endif    fd = -1;    fetchConnectionParameters();    QIODevice::close();}/*!    Returns true if the socket is valid and in blocking mode;    otherwise returns false.    Note that this function does not set error().    \warning On Windows, this function always returns true since the    ioctlsocket() function is broken.    \sa setBlocking(), isValid()*/bool Q3SocketDevice::blocking() const{    if ( !isValid() )	return true;    int s = fcntl(fd, F_GETFL, 0);    return !(s >= 0 && ((s & O_NDELAY) != 0));}/*!    Makes the socket blocking if \a enable is true or nonblocking if    \a enable is false.    Sockets are blocking by default, but we recommend using    nonblocking socket operations, especially for GUI programs that    need to be responsive.    \warning On Windows, this function should be used with care since    whenever you use a QSocketNotifier on Windows, the socket is    immediately made nonblocking.    \sa blocking(), isValid()*/void Q3SocketDevice::setBlocking( bool enable ){#if defined(QSOCKETDEVICE_DEBUG)    qDebug( "Q3SocketDevice::setBlocking( %d )", enable );#endif    if ( !isValid() )	return;    int tmp = ::fcntl(fd, F_GETFL, 0);    if ( tmp >= 0 )	tmp = ::fcntl( fd, F_SETFL, enable ? (tmp&~O_NDELAY) : (tmp|O_NDELAY) );    if ( tmp >= 0 )	return;    if ( e )	return;    switch( errno ) {    case EACCES:    case EBADF:	e = Impossible;	break;    case EFAULT:    case EAGAIN:#if EAGAIN != EWOULDBLOCK    case EWOULDBLOCK:#endif    case EDEADLK:    case EINTR:    case EINVAL:    case EMFILE:    case ENOLCK:    case EPERM:    default:	e = UnknownError;    }}/*!    Returns the value of the socket option \a opt.*/int Q3SocketDevice::option( Option opt ) const{    if ( !isValid() )	return -1;    int n = -1;    int v = -1;    switch ( opt ) {    case Broadcast:	n = SO_BROADCAST;	break;    case ReceiveBuffer:	n = SO_RCVBUF;	break;    case ReuseAddress:	n = SO_REUSEADDR;	break;    case SendBuffer:	n = SO_SNDBUF;	break;    }    if ( n != -1 ) {	QT_SOCKOPTLEN_T len;	len = sizeof(v);	int r = ::getsockopt( fd, SOL_SOCKET, n, (char*)&v, &len );	if ( r >= 0 )	    return v;	if ( !e ) {	    Q3SocketDevice *that = (Q3SocketDevice*)this; // mutable function	    switch( errno ) {	    case EBADF:	    case ENOTSOCK:		that->e = Impossible;		break;	    case EFAULT:		that->e = InternalError;		break;	    default:		that->e = UnknownError;		break;	    }	}	return -1;    }    return v;}/*!    Sets the socket option \a opt to \a v.*/void Q3SocketDevice::setOption( Option opt, int v ){    if ( !isValid() )	return;    int n = -1; // for really, really bad compilers    switch ( opt ) {    case Broadcast:	n = SO_BROADCAST;	break;    case ReceiveBuffer:	n = SO_RCVBUF;	break;    case ReuseAddress:	n = SO_REUSEADDR;	break;    case SendBuffer:	n = SO_SNDBUF;	break;    default:	return;    }    if ( ::setsockopt( fd, SOL_SOCKET, n, (char*)&v, sizeof(v)) < 0 &&	 e == NoError ) {	switch( errno ) {	case EBADF:	case ENOTSOCK:	    e = Impossible;	    break;	case EFAULT:	    e = InternalError;	    break;	default:	    e = UnknownError;	    break;	}    }}/*!    Connects to the IP address and port specified by \a addr and \a    port. Returns true if it establishes a connection; otherwise returns false.    If it returns false, error() explains why.    Note that error() commonly returns NoError for non-blocking    sockets; this just means that you can call connect() again in a    little while and it'll probably succeed.*/bool Q3SocketDevice::connect( const QHostAddress &addr, Q_UINT16 port ){    if ( !isValid() )	return false;    pa = addr;    pp = port;    struct sockaddr_in a4;    struct sockaddr *aa;    QT_SOCKLEN_T aalen;#if !defined(QT_NO_IPV6)    struct sockaddr_in6 a6;    if ( addr.isIPv6Address() ) {	memset( &a6, 0, sizeof(a6) );	a6.sin6_family = AF_INET6;	a6.sin6_port = htons( port );	Q_IPV6ADDR ip6 = addr.toIPv6Address();	memcpy( &a6.sin6_addr.s6_addr, &ip6, sizeof(ip6) );	aalen = sizeof( a6 );	aa = (struct sockaddr *)&a6;    } else#endif    if ( addr.isIPv4Address() ) {	memset( &a4, 0, sizeof(a4) );	a4.sin_family = AF_INET;	a4.sin_port = htons( port );	a4.sin_addr.s_addr = htonl( addr.toIPv4Address() );	aalen = sizeof(a4);	aa = (struct sockaddr *)&a4;    } else {	e = Impossible;	return false;    }    int r = QT_SOCKET_CONNECT( fd, aa, aalen );    if ( r == 0 ) {	fetchConnectionParameters();	return true;    }    if ( errno == EISCONN || errno == EALREADY || errno == EINPROGRESS ) {	fetchConnectionParameters();	return true;    }    if ( e != NoError || errno == EAGAIN || errno == EWOULDBLOCK ) {	return false;    }    switch( errno ) {    case EBADF:    case ENOTSOCK:	e = Impossible;	break;    case EFAULT:    case EAFNOSUPPORT:	e = InternalError;	break;    case ECONNREFUSED:	e = ConnectionRefused;	break;    case ETIMEDOUT:    case ENETUNREACH:	e = NetworkFailure;	break;    case EADDRINUSE:	e = NoResources;	break;    case EACCES:    case EPERM:	e = Inaccessible;	break;    default:	e = UnknownError;	break;    }    return false;}/*!    Assigns a name to an unnamed socket. The name is the host address    \a address and the port number \a port. If the operation succeeds,    bind() returns true; otherwise it returns false without changing    what port() and address() return.    bind() is used by servers for setting up incoming connections.    Call bind() before listen().*/bool Q3SocketDevice::bind( const QHostAddress &address, Q_UINT16 port ){    if ( !isValid() )	return false;    int r;    struct sockaddr_in a4;#if !defined(QT_NO_IPV6)    struct sockaddr_in6 a6;    if ( address.isIPv6Address() ) {	memset( &a6, 0, sizeof(a6) );	a6.sin6_family = AF_INET6;	a6.sin6_port = htons( port );	Q_IPV6ADDR tmp = address.toIPv6Address();	memcpy( &a6.sin6_addr.s6_addr, &tmp, sizeof(tmp) );	r = QT_SOCKET_BIND( fd, (struct sockaddr *)&a6, sizeof(a6) );    } else#endif    if ( address.isIPv4Address() ) {	memset( &a4, 0, sizeof(a4) );	a4.sin_family = AF_INET;	a4.sin_port = htons( port );	a4.sin_addr.s_addr = htonl( address.toIPv4Address() );	r = QT_SOCKET_BIND( fd, (struct sockaddr*)&a4, sizeof(a4) );    } else {	e = Impossible;	return false;    }    if ( r < 0 ) {	switch( errno ) {	case EINVAL:	    e = AlreadyBound;	    break;	case EACCES:	    e = Inaccessible;	    break;	case ENOMEM:	    e = NoResources;	    break;	case EFAULT: // a was illegal	case ENAMETOOLONG: // sz was wrong	    e = InternalError;	    break;	case EBADF: // AF_UNIX only	case ENOTSOCK: // AF_UNIX only	case EROFS: // AF_UNIX only	case ENOENT: // AF_UNIX only	case ENOTDIR: // AF_UNIX only	case ELOOP: // AF_UNIX only	    e = Impossible;	    break;	default:	    e = UnknownError;	    break;	}	return false;    }    fetchConnectionParameters();    return true;}

⌨️ 快捷键说明

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