Socket Engine

 

Socket Engine

Using English to describe my idea is so hard for me, but I should take the bull by horns. I know that English will be accompanied by my life. So I must work hard to make it better. Are you in the same page with me? If you agree with me, here we go.

The creative spirit is so important in our daily life, so we need try to think out of the box everywhere.

Now let’s come to today’s analyze of socket engine.

First, let’s find where the object of QAbstractSocketEngine is created.

In the QTcpServerPrivate class, I find the pointer of QAbstractSocketEngine class. So let’s come to the constructor of QAbstractSocketEngine.

QTcpServerPrivate::QTcpServerPrivate()

 : port(0)

 , state(QAbstractSocket::UnconnectedState)

 , socketEngine(0)

 , serverSocketError(QAbstractSocket::UnknownSocketError)

 , maxConnections(30)

{

}

The only thing is to set the socket engine pointer to NULL.

In the listen () function, they call the createSocketEngine () function.

d->socketEngine = QAbstractSocketEngine::createSocketEngine(QAbstractSocket::TcpSocket, proxy, this);

Here is the realization of createSocketEngine.

QAbstractSocketEngine *QAbstractSocketEngine::createSocketEngine(QAbstractSocket::SocketType socketType, const QNetworkProxy &proxy, QObject *parent)

{

#ifndef QT_NO_NETWORKPROXY

    // proxy type must have been resolved by now

    if (proxy.type() == QNetworkProxy::DefaultProxy)

        return 0;

#endif

 

    QMutexLocker locker(&socketHandlers()->mutex);

    for (int i = 0; i < socketHandlers()->size(); i++) {

        if (QAbstractSocketEngine *ret = socketHandlers()->at(i)->createSocketEngine(socketType, proxy, parent))

            return ret;

    }

 

#ifndef QT_NO_NETWORKPROXY

    // only NoProxy can have reached here

    if (proxy.type() != QNetworkProxy::NoProxy)

        return 0;

#endif

 

    return new QNativeSocketEngine(parent);

}

Here we can see the QNativeSocketEngine object was created.

In the constructor of QNativeSocketEngine class, the object of QNativeSocketEnginePrivate was created.

QNativeSocketEngine::QNativeSocketEngine(QObject *parent)

    : QAbstractSocketEngine(*new QNativeSocketEnginePrivate(), parent)

{

}

QNativeSocketEnginePrivate::QNativeSocketEnginePrivate()

{

    socketDescriptor = -1;

    readNotifier = 0;

    writeNotifier = 0;

    exceptNotifier = 0;

}

After the object was created, the initialize () function was called.

if (!d->socketEngine->initialize(QAbstractSocket::TcpSocket, proto)) {

        d->serverSocketError = d->socketEngine->error();

        d->serverSocketErrorString = d->socketEngine->errorString();

        return false;

    }

The description of initialize () function.

/*!

    Initializes a QNativeSocketEngine by creating a new socket of type /a

    socketType and network layer protocol /a protocol. Returns true on

    success; otherwise returns false.

 

    If the socket was already initialized, this function closes the

    socket before reeinitializing it.

 

    The new socket is non-blocking, and for UDP sockets it's also

    broadcast enabled.

*/

First, they create the new socket by call the createNewSocket () function from QNativeSocketEnginePrivate class.

Then, here is something we need attention on Qt4.6.0.

// Before Qt 4.6, we always set the send and receive buffer size to 49152 as

    // this was found to be an optimal value. However, modern OS

    // all have some kind of auto tuning for this and we therefore don't set

    // this explictly anymore.

    // If it introduces any performance regressions for Qt 4.6.x (x > 0) then

    // it will be put back in.

    //

    // You can use tests/manual/qhttpnetworkconnection to test HTTP download speed

    // with this.

    //

    // pre-4.6:

    // setReceiveBufferSize(49152);

    // setSendBufferSize(49152);

End of this function, they save the socket information.

d->socketType = socketType;

d->socketProtocol = protocol;

Then the bind () function was called. In this function, nativeBind () function was called.

if (!d->nativeBind(address, port))

     return false;

The nativeBind () function is an platform-specific function. Let’s look the version of windows.

In the qnativesocketengine_win.cpp, I have seen the createNewSocket () function. Create a windows socket by call this.

SOCKET socket = ::WSASocket(protocol, type, 0, NULL, 0, WSA_FLAG_OVERLAPPED);

Here is the realization by using win32 API function.

qt_socket_setPortAndAddress(socketDescriptor, &sockAddrIPv4, &sockAddrIPv6, port, address, &sockAddrPtr, &sockAddrSize);

int bindResult = ::bind(socketDescriptor, sockAddrPtr, sockAddrSize);

And the nativeListen () function is on the same page.

if (::listen(socketDescriptor, backlog) == SOCKET_ERROR)

Here is all the analyzing today. Next day, I will continue this part.

 

November 16, 2009 23:20

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值