Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15814
  • 博文数量: 5
  • 博客积分: 1536
  • 博客等级: 上尉
  • 技术积分: 60
  • 用 户 组: 普通用户
  • 注册时间: 2009-03-18 18:58
文章分类

全部博文(5)

文章存档

2012年(1)

2011年(4)

我的朋友

分类: C/C++

2011-05-03 09:13:04

在QWSServerPrivate::initServer(int flags)里定义了
    clientMap[-1] = new QWSClient(q, 0, 0);
代表服务器所在程序的客户端。clientMap不是数组,是一个QMap。
在QWSServerPrivate::_q_newConnection()里创建一个管理非服务器所在程序的
    QWSClient *client = new QWSClient(q,sock, get_object_id());
而QWSServerPrivate::_q_newConnection()是经由
    QObject::connect(ssocket, SIGNAL(newConnection()), q, SLOT(_q_newConnection()));
调用的。上一句也是在QWSServerPrivate::initServer(int flags)里调用的。其中ssocket是一个QWSServerSocket。而QWSClient(q,sock, get_object_id())中的sock不是ssocket,而是一个QWSSocket。SIGNAL(newConnection())信号在
    void QWSServerSocket::incomingConnection(int socketDescriptor)
中产生。而QWSServerSocket::incomingConnection(int socketDescriptor)是虚函数,在基类中有原型。且是在QWSServerSocket的基类中调用。QWSServerSocket的基类根据
    QT_NO_SXE
选项分为QUnixSocketServer和QTcpServer。QT_NO_SXE中SXE的意思应该是safe execute environment的意思。所以我感觉这个选项意义不大。如果为QUnixSocketServer,则QWSServerSocket::incomingConnection(int socketDescriptor)在
    void QUnixSocketServerPrivate::acceptActivated()
中调用。acceptActivated()函数调用
    int connsock = ::accept(fd, (sockaddr *)&r, &len);
检查并接受客户端的请求,同时产生一个新的socket。acceptActivated()本身是一个槽函数。
        QObject::connect(d->acceptNotifier, SIGNAL(activated(int)),
                     d, SLOT(acceptActivated()));
d就是QUnixSocketServerPrivate本身。类QUnixSocketServerPrivate不是在其子类实例化时或QUnixSocketServer实例化时产生的,而是在
    bool QUnixSocketServer::listen(const QByteArray & path)
中产生的。而上面的函数是在
    void QWSServerSocket::init(const QString &file)
中调用的。
在QUnixSocketServerPrivate产生之后,该函数打开了一个unix套接字,然后调用
    d->acceptNotifier = new QSocketNotifier(d->fd, QSocketNotifier::Read, d);
产生一个QSocketNotifier监视该套接字。QSocketNotifier在构造时会把自己注册进系统,由系统消息循环统一管理。QSocketNotifier的SIGNAL(activated(int))是在
    bool QSocketNotifier::event(QEvent *e)
中产生的。这里我有个疑问,这个函数是protected的,而整个系统中它没子类,且类中别的函数没调用这个函数,可是,如果这个函数没被调用,这里所说的一切都可能是错的。这个函数中有如下语句
        if (e->type() == QEvent::SockAct) {
        emit activated(sockfd);
        return true;
    }
QEvent::SockAct事件比较特殊,它既不是服务器发给客户应用程序的事件,也不是客户应用程序发给服务器的命令。它是检测到QSocketNotifier变化后产生的事件,也就是说,所有的系统事件都是在它产生之后产生的。而该事件是在
    int QEventDispatcherUNIX::activateSocketNotifiers()
中产生的。在上面函数中,通过查询QEventDispatcherUNIXPrivate中的sn_pending_list是否为空来决定是否发送QEvent::SockAct事件。sn_pending_list是通过
    void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier)
函数来填充的。而这个函数是在
    int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags,
        timeval *timeout)
中调用的。doSelect()函数在调用setSocketNotifierPending()之后调用
    int QEventDispatcherUNIX::activateSocketNotifiers()
函数。doSelect()函数很有学问,值得膜拜。doSelect()函数在
    bool QEventDispatcherUNIX::processEvents(QEventLoop::ProcessEventsFlags flags)
中调用。上面的函数在
    bool QEventDispatcherQWS::processEvents(QEventLoop::ProcessEventsFlags flags)
中调用。而上面的函数在QWS系统中是最重要的事件处理函数。
 
从下往上看,就是QWSClient的建立过程。
阅读(830) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:客户端程序建立和服务器通信

给主人留下些什么吧!~~