• 9228阅读
  • 7回复

关于tcpServer典型例子使用的一个问题 [复制链接]

上一主题 下一主题
离线iiiyyyhhhsss
 

只看楼主 倒序阅读 楼主  发表于: 2010-03-06
— 本帖被 XChinux 从 General Qt Programming 移动到本区(2011-01-02) —
以下是典型例子中的关键代码部分,大家应该看得明白的

connect(this->tcpServer,SIGNAL(newConnection()),this,SLOT(AcceptConnection()));

void MTcpServer::AcceptConnection()                  //接收连接
{this->tcpSocket=this->tcpServer->nextPendingConnection();
connect(this->tcpSocket,SIGNAL(readyRead()),this,SLOT(ReadTcpSocket()));}

void MTcpServer::ReadTcpSocket()            //读取数据
{  this->tcpSocket->readAll();}


我的问题是,当有很多连接请求在某一较短的时间段出现时,以上代码不会出现错误吗?

举例:


假设有套接字A和B,同时处于连接状态中....

如果某个时刻this->tcpSocket指向套接字B(我们知道不可能同时指向两个套接字的),

而套接字A此时有数据来了,触发槽函数去读取this->tcpSocket指向的套接字的数据,

由于此时this->tcpSocket指向套接字B,也就是说A有数据来了,却触发槽函数去读取B的数据?
[ 此帖被iiiyyyhhhsss在2010-03-06 17:18重新编辑 ]
离线午小夜

只看该作者 1楼 发表于: 2010-03-06
tcp & udp的區別,查查看。
[操作系统版本]  Windows XP;Linux Ubuntu;Linux Fedora;
[Qt SDK版本]    4.7.0
[SDK 发布日期]  2010.05
[IDE(集成开发环境)] QtCreator
个人网页:http://hi.baidu.com/午小夜
學歷:Royal Jalidon
离线iiiyyyhhhsss

只看该作者 2楼 发表于: 2010-03-06
引用第1楼午小夜于2010-03-06 12:19发表的  :
tcp & udp的區別,查查看。



两者之间的区别我知道....

我只是对代码不理解,不理解的地方就是上面所说
[ 此帖被iiiyyyhhhsss在2010-03-06 14:27重新编辑 ]
离线iiiyyyhhhsss

只看该作者 3楼 发表于: 2010-03-06
想想看,此时"连接1"和"连接2"不断有数据来时,都触发各自的readyRead()信号

但是两个信号均连接到槽ReadTcpSocket()

然后执行this->tcpSocket->readAll();

但是此时此刻的this->tcpSocket只能是其中的一个套接字的指针,要么是1的,要么是2的

不可能来回切换套接字的指针,以读取两个连接的数据吧
离线dbzhang800

只看该作者 4楼 发表于: 2010-03-06
引用第3楼iiiyyyhhhsss于2010-03-06 14:05发表的  :
想想看,此时"连接1"和"连接2"不断有数据来时,都触发各自的readyRead()信号
但是两个信号均连接到槽ReadTcpSocket()
然后执行this->tcpSocket->readAll();
.......


采用多线程,来一个连接,开一个线程来处理。

可找本网络编程的书看看
离线iiiyyyhhhsss

只看该作者 5楼 发表于: 2010-03-06
引用第4楼dbzhang800于2010-03-06 14:43发表的  :
采用多线程,来一个连接,开一个线程来处理。
可找本网络编程的书看看



多线程的socket变成我也懂,我也写过了

我不是不明白网络多线程处理的过程,我只是想分析清楚以下这句信号槽的意思:

connect(this->tcpSocket,SIGNAL(readyRead()),this,SLOT(ReadTcpSocket()));

它的意思不是这样吗:  当this->tcpSocket指向的套接字有数据来到时,就执行函数ReadTcpSocket()

但是,任何时候this->tcpSocket指针只能指向一个套接字....

我记得用C++标准库里的Socket库编程时,对每个套接字都会有一个套接字字符指向套接字的,即与之对应

但是这里却只有一个this->tcpSocket,怎么够用?Qt里是怎么处理这个转换的?

我们任何时候执行this->tcpSocket->readAll(),不是都只是读取一个套接字里的内容吗?
[ 此帖被iiiyyyhhhsss在2010-03-06 16:36重新编辑 ]
离线iiiyyyhhhsss

只看该作者 6楼 发表于: 2010-03-06
void MTcpServer::ReadTcpSocket()            //读取数据
{  this->tcpSocket->readAll();}

这个槽函数的意思,不就是说,当有数据来的时候,

就读取指针this->tcpSocket指向的套接字的内容吗?

假设有套接字A和B,同时处于连接状态中....

如果某个时刻this->tcpSocket指向套接字B(我们知道不可能同时指向两个套接字的),

而套接字A此时有数据来了,触发槽函数去读取this->tcpSocket指向的套接字的数据,

由于此时this->tcpSocket指向套接字B,也就是说A有数据来了,却触发槽函数去读取B的数据?
离线yushan
只看该作者 7楼 发表于: 2012-04-05
我的确碰到了这样的问题,代码如下:

mytcpserver.h

#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H

#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>


class MyTcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit MyTcpServer( QObject *parent = 0 );
    bool myTcpServerListen( const int serverport, const int maxconnect );
    void myTcpServerStop();

private:
    QTcpServer*         mytcpserver;
    QTcpSocket*         mytcpsocket;
    QList<QTcpSocket*>  mytcpsocketlist;
    int                 maxtcpsocket;

private slots:
    void tcpserver_recv_slot();
    void tcpserver_connect_slot();
    void tcpserver_display_error();

};

#endif // MYTCPSERVER_H


mytcpserver.cpp

#include "mytcpserver.h"

MyTcpServer::MyTcpServer(QObject *parent) :
    QTcpServer(parent)
{
    /// 声明TCP服务
    mytcpserver = new QTcpServer( this );
    mytcpsocket = new QTcpSocket( this );

    connect(mytcpserver,SIGNAL(newConnection()),this,SLOT(tcpserver_connect_slot()));
}

bool MyTcpServer::myTcpServerListen( const int serverport, const int maxconnect )
{

    /// 监听
    if( false == mytcpserver->listen(QHostAddress::Any,serverport) )
    {
        qDebug() << QObject::tr( "ERROR: 绑定端口失败..." );
        return false;
    }

    /// 设置槽及最大连接数
    maxtcpsocket  = maxconnect;


    qDebug() << QObject::tr( "SUCCESS: 绑定服务器端口成功." );
    return TRUE;
}

void MyTcpServer::myTcpServerStop( )
{
    for( int i = 0; i < mytcpsocketlist.count(); i++ )
    {
        mytcpsocketlist.at(i)->close();
        mytcpsocketlist.removeAt(i);
    }

    mytcpsocketlist.clear();
    mytcpserver->close();
}

void MyTcpServer::tcpserver_connect_slot()
{
    qDebug() << QObject::tr( "SUCCESS: 有客户端请求连接, 现已经接受请求数为:" ) << mytcpsocketlist.count();

    if( mytcpsocketlist.count() <= maxtcpsocket )
    {
          qDebug() << QObject::tr( "SUCCESS: 客户端连接请求已接受..." );

          mytcpsocket = mytcpserver -> nextPendingConnection();
          connect(mytcpsocket,SIGNAL(readyRead()),this,SLOT(tcpserver_recv_slot()));
          connect(mytcpsocket,SIGNAL(disconnected()),mytcpsocket,SLOT(deleteLater()));
          mytcpsocketlist.append( mytcpsocket );
          qDebug() << QObject::tr( "SUCCESS: 已接受请求数:" ) << mytcpsocketlist.count();
    }
    else
    {
        qDebug() << QObject::tr( "ERROR: 系统连接超过允许的最大上限..." );
    }
}

void MyTcpServer::tcpserver_recv_slot()
{
    qDebug() << QObject::tr( "SUCCESS: 客户端发送数据请求..." );

    for( int i=0 ; i< mytcpsocketlist.count() ; i++ )
    {
        QByteArray inblock;
        mytcpsocket = mytcpsocketlist.at(i);

        if( mytcpsocket->isReadable() )
        {
            inblock = mytcpsocket->readAll();
            QString inbuff = QString( inblock );

            if( inbuff.length() == 0 )
            {
                qDebug() << QObject::tr( "ERROR: 客户端无数据传送, 连接编号: " ) << i << mytcpsocket->isReadable();
                continue;
            }

            qDebug() << QObject::tr( "SUCCESS: 数据接收完成." );
            qDebug() << inbuff << inblock.size();

            /// 调用业务业务处理组件
            QString outbuff;
            /*
            MyBusiness myBusiness;
            myBusiness.MyBusMain( inbuff, outbuff );
    */

            if( outbuff.length() == 0 )
            {
                outbuff = "transaction success.";
            }

            qDebug() << QObject::tr( "SUCCESS: 开始向客户端发送数据, 连接编号为: " ) << i;
            qDebug() << QObject::tr( "SUCCESS: 向客户端返回数据..." );

            /// 向客户端发送数据
            mytcpsocket->write( outbuff.toAscii() );

            /// 关闭TCP连接
            mytcpsocketlist.replace(i, mytcpsocketlist.last() );
            mytcpsocketlist.removeLast();
            mytcpsocket->disconnectFromHost();

        }
    }
}

void MyTcpServer::tcpserver_display_error()
{
    qDebug() << QObject::tr( "ERROR: 系统连接错误..." ) << mytcpserver->errorString();

}
同时建立多次连接后,会跑出N多SOCKET都发送readyRead信号,很郁闷。。。。。
后飞的笨鸟
快速回复
限100 字节
 
上一个 下一个