• 6952阅读
  • 2回复

[提问]Qt的tcp服务器(QTcpServer)问题 [复制链接]

上一主题 下一主题
离线hjkcai
 
只看楼主 倒序阅读 楼主  发表于: 2011-12-04
我自己做了一个简单的服务器,可是客户端连接再断开后,服务器没有办法立即重新开始监听,是为什么呢?


错误信息:server.exe 中的 0x015180c7 处有未经处理的异常: 0xC0000005: 读取位置 0xfeeefeee 时发生访问冲突
调用堆栈:

server.exe!QAbstractSocketPrivate::resetSocketLayer()  行 508 + 0x12 字节    
server.exe!QAbstractSocketPrivate::readFromSocket()  行 1184    
server.exe!QAbstractSocketPrivate::canReadNotification()  行 618 + 0x8 字节    
server.exe!QAbstractSocketPrivate::readNotification()  行 77 + 0x15 字节    
server.exe!QAbstractSocketEngine::readNotification()  行 155    
server.exe!QReadNotifier::event(QEvent * e)  行 1104    
server.exe!QApplicationPrivate::notify_helper(QObject * receiver, QEvent * e)  行 4481 + 0x11 字节    
server.exe!QApplication::notify(QObject * receiver, QEvent * e)  行 3881 + 0x10 字节    
server.exe!QCoreApplication::notifyInternal(QObject * receiver, QEvent * event)  行 787 + 0x15 字节    
server.exe!QCoreApplication::sendEvent(QObject * receiver, QEvent * event)  行 215 + 0x39 字节    
server.exe!qt_internal_proc(HWND__ * hwnd, unsigned int message, unsigned int wp, long lp)  行 485 + 0xf 字节    
user32.dll!76acc4e7()    
[下面的框架可能不正确和/或缺失,没有为 user32.dll 加载符号]    
user32.dll!76acc5e7()    
user32.dll!76acc590()    
user32.dll!76accc19()    
user32.dll!76accc70()    
server.exe!QEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags)  行 810    
server.exe!QGuiEventDispatcherWin32::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags)  行 1170 + 0x14 字节    
server.exe!QEventLoop::processEvents(QFlags<enum QEventLoop::ProcessEventsFlag> flags)  行 150    
server.exe!QEventLoop::exec(QFlags<enum QEventLoop::ProcessEventsFlag> flags)  行 201 + 0x2d 字节    
server.exe!QCoreApplication::exec()  行 1064 + 0x15 字节    
server.exe!QApplication::exec()  行 3756    
server.exe!main(int argc, char * * argv)  行 12 + 0x5 字节    
server.exe!WinMain(HINSTANCE__ * instance, HINSTANCE__ * prevInstance, char * __formal, int cmdShow)  行 131 + 0x12 字节    
server.exe!__tmainCRTStartup()  行 547 + 0x2c 字节
server.exe!WinMainCRTStartup()  行 371


代码:
  1. #include <QWidget>
  2. #include <QtNetwork>
  3. #define connect_port 678
  4. class server : public QObject
  5. {
  6.     Q_OBJECT
  7. public:
  8.     explicit server();
  9.     void createServer();
  10.     void sendData(QByteArray data);
  11.     void stopServer();
  12.     QTcpServer *stcp;
  13.     QTcpSocket *tcp;
  14. signals:
  15.     void clientConnected();
  16.     void clientError(QString err);
  17.     void readyRead(QByteArray data);
  18.     void startListen();
  19.     void stopListen();
  20. private:
  21. private slots:
  22.     void client_readyRead();
  23.     void client_error(QAbstractSocket::SocketError err);
  24.     void newConnection();
  25. };
  26. //server.cpp
  27. #include "server.h"
  28. server::server()
  29. {
  30.     tcp = NULL;
  31.     stcp = NULL;
  32. }
  33. void server::createServer()
  34. {
  35.     stopServer();
  36.     stcp = new QTcpServer(this);
  37.     connect(stcp, SIGNAL(newConnection()), this, SLOT(newConnection()));
  38.     stcp->listen(QHostAddress::Any, connect_port);
  39.     emit startListen();
  40. }
  41. void server::sendData(QByteArray data)
  42. {
  43.     if (tcp)
  44.         tcp->write(data);
  45. }
  46. void server::stopServer()
  47. {
  48.     if (tcp)
  49.     {
  50.         tcp->abort();
  51.         delete tcp;
  52.         tcp = NULL;
  53.     }
  54.     if (stcp)
  55.     {
  56.         //stcp->close();
  57.         delete stcp;
  58.         stcp = NULL;
  59.     }
  60.     emit stopListen();
  61. }
  62. void server::client_error(QAbstractSocket::SocketError err)
  63. {
  64.     emit clientError(tcp->errorString());
  65.     createServer();    //将这句注释后,就不再出错了
  66. }
  67. void server::client_readyRead()
  68. {
  69.     emit readyRead(tcp->readAll());
  70. }
  71. void server::newConnection()
  72. {
  73.     tcp = stcp->nextPendingConnection();
  74.     connect(tcp, SIGNAL(readyRead()), this, SLOT(client_readyRead()));
  75.     connect(tcp, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(client_error(QAbstractSocket::SocketError)));
  76.     stcp->close();
  77.     emit clientConnected();
  78. }

客户端部分我还没有自己重新做一个,用的是http://code.google.com/p/jybox/source/browse/#svn%2FJyIM%2FDemo1x里面的c.exe(也是使用qt编写的,代码在左边的“C”目录下)。我想应该没有很大的关系。但是这里面的服务端程序(“s.exe”)就能够在客户端断开后立即重新开始监听,我的代码就是模仿它写的,为什么就不能了呢?


编译器:VS 2010 && Qt 4.7.4
离线wxj120bw

只看该作者 1楼 发表于: 2011-12-05
回 楼主(hjkcai) 的帖子
服务端QTcpServer应该一直处于监听中 “可是客户端连接再断开后,服务器没有办法立即重新开始监听”该怎么理解
离线hjkcai
只看该作者 2楼 发表于: 2011-12-05
回 1楼(wxj120bw) 的帖子
这个代码只是支持一个客户端连接的,客户端连接后就停止监听了,所以在客户端断开后要立即重新开始监听。
快速回复
限100 字节
 
上一个 下一个