• 4932阅读
  • 7回复

Tcp网络编程 [复制链接]

上一主题 下一主题
 

只看楼主 倒序阅读 楼主  发表于: 2015-08-08
下面是我写的一个Tcp服务器和客户端通信的一个小程序,求大神能帮忙看看问题
服务器端
//.h
#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>
#include <QList>
#include <QMutex>
#include <QString>
#include <QTimer>


class MyTcpServer : public QThread
{  
    Q_OBJECT


       public:
                   MyTcpServer();  
                   virtual ~MyTcpServer();  
                    void Start();
       signals:
       public slots:
                   void SendResult();
           private:    class ProcessDataThread : public QThread
          {    
                  public:        ProcessDataThread(MyTcpServer * server):_server(server){}
                  private:        
                           virtual void run()
                          {
                                   _server->ProcessData();
                           }  


                           MyTcpServer *_server;
            };
            private:
                   void ProcessData();
            private:  
                   void AcceptSocket();
                   virtual void run();
                   void ReceiveData();
                   void CreateThread();
                   void Clear();

                    QTcpSocket *_connectSocket;
                    QTcpServer *_listenSocket;
                    bool _linkState;
                    QList<QString> _dataList;
                   QList<QString> _resultList;
                   QMutex _dataMutex;
                   QMutex _resultMutex;
                    ProcessDataThread *_processDataThread;
                    QTimer *_timer;
};
#endif // MYTCPSERVER_H

//服务器端.CPP
#include "mytcpserver.h"
#include <QMutexLocker>
#include <iostream>
using std::cout;
using std::endl;

MyTcpServer::MyTcpServer():_linkState(false),_processDataThread(NULL){    _listenSocket = new QTcpServer(this);    _connectSocket = new QTcpSocket(this);}

MyTcpServer::~MyTcpServer()
{  
     terminate();  
     wait();  
     if(NULL != _listenSocket){
           _listenSocket->close();  
          delete _listenSocket;
          _listenSocket = NULL;  
      }  
      if(NULL != _connectSocket){
             _connectSocket->close();  
            delete _connectSocket;  
           _connectSocket = NULL;  
       }  
       Clear();
      _linkState = false;
}


void MyTcpServer::Start()
{  
          cout << "server:: Listen is start..." << endl;  
        _listenSocke->listen(QHostAddress::Any, 6666);
        _timer = new QTimer();  
        connect(_timer, SIGNAL(timeout()), this, SLOT(SendResult()));
        _timer->start(1000);  
       start();
}


void MyTcpServer::AcceptSocket()
{  
      if(!_listenSocket->waitForNewConnection(-1)){  
            cout << "server:: connect is fail!" << endl;
            _linkState = false;
            return;    
       }  
       _connectSocket = _listenSocket->nextPendingConnection();
       _linkState = true;
      cout << "server:: connect is ok!" << endl;
}


void MyTcpServer::run()
{
    while(1){
       AcceptSocket();
       CreateThread();
       ReceiveData();  
      Clear();
   }
}


void MyTcpServer::ReceiveData()
{  
  while(1){  
      if(!_connectSocket->waitForReadyRead(-1)){
            _linkState = false;
           _connectSocket->close();  
           break;
        }
       cout << "server::Start receive data..." << endl;
       QByteArray receiveData = _connectSocket->readAll();
       if(receiveData.isEmpty()){        
             msleep(500);  
             continue;  
       }  
      QString data(receiveData);
      QMutexLocker mutexLocker(&_dataMutex);  
      _dataList.prepend(data);  
      cout << "server::ReceiveData== " << data.toStdString() << endl;
   }
}


void MyTcpServer::ProcessData()
{    
       while(1){    
           QString data;
           QMutexLocker mutexLocker(&_dataMutex);      
           if(!_dataList.isEmpty()){          
                 data = _dataList.takeAt(0);  
           }else{  
                 msleep(500);  
                 continue;  
     }      
     mutexLocker.unlock();
      QMutexLocker locker(&_resultMutex);
       _resultList.prepend(data);  
      cout << "server::ProcessData== " << data.toStdString() << endl;
       msleep(200);  
}
}


void MyTcpServer::CreateThread()
{    
     _processDataThread = new ProcessDataThread(this);
     _processDataThread->start();
}


void MyTcpServer::Clear()
{  
      if(NULL != _processDataThread){      
            _processDataThread->terminate();  
            _processDataThread->wait();
            delete _processDataThread;  
           _processDataThread = NULL;
      }
}




void MyTcpServer::SendResult()
{  
      if(!_linkState)return;
      if(3 != _connectSocket->state())return;
      if(_resultList.isEmpty())return;  
      QMutexLocker mutexLocker(&_resultMutex);  
      QString data = _resultList.takeAt(0);
      cout << "server::SendResult== " << data.toStdString() << endl;
      mutexLocker.unlock();  
      _connectSocket->write(data.toLatin1());  
      _connectSocket->waitForBytesWritten(-1);
}


客户端//.h
#ifndef MYTCPSOCKET_H
#define MYTCPSOCKET_H
#include <QTcpSocket>
#include <QThread>
#include <QList>
#include <QString>
#include <QMutex>
#include <QMutexLocker>


class MyTcpSocket : public QThread
{    
Q_OBJECT
public:
          explicit MyTcpSocket();
          virtual ~MyTcpSocket();  
          QString SendData(const QString& data);
          void PostData(const QString& data);  
          void Start();  
          void Stop();
private:  
          void ReceiveData();
          virtual void run();
signals:
public slots:
private:
           void Connect();  
           QTcpSocket *_connectSocket;
           bool _linkState;
           QList<QString> _dataList;
           QMutex _mutex;
};
#endif // MYTCPSOCKET_H
//.cpp文件
#include "mytcpsocket.h"
#include <QHostAddress>
#include <iostream>
using std::cout;
using std::endl;

MyTcpSocket::MyTcpSocket():_linkState(false)
{    _connectSocket = new QTcpSocket();    _dataList.clear();}

MyTcpSocket::~MyTcpSocket()
{
   if(NULL != _connectSocket){
       delete _connectSocket;
        _connectSocket = NULL;
    }
}


void MyTcpSocket::Start()
{
    start();
}


QString MyTcpSocket::SendData(const QString &data)
{
   if(3 == _connectSocket->state()){
       _connectSocket->write(data.toLatin1());
       if(!_connectSocket->waitForBytesWritten(-1)){
           _linkState = false;
       }
   }
}


void MyTcpSocket::PostData(const QString& data)
{}


void MyTcpSocket::Connect()
{
   cout << "Client:: connect is start..." << endl;
    _connectSocket->connectToHost("127.0.0.1", 6666);
   if(!_connectSocket->waitForConnected(-1)){
       return;
   }
   _linkState = true;
    cout << "Client:: connect is ok!" << endl;
}


void MyTcpSocket::ReceiveData()
{
    while(1){
       if(!_connectSocket->waitForReadyRead(-1)){
          _linkState = false;
            _connectSocket->close();
            break;
       }
       QByteArray arr = _connectSocket->readAll();
       if(arr.isEmpty()){
           msleep(500);
            continue;
       }
        QMutexLocker locker(&_mutex);
        QString data(arr);
       _dataList.prepend(data);
        cout << "Client::ReceiveData==" << data.toStdString() << endl;
    }
}


void MyTcpSocket::run()
{
   while(!_linkState)    {
        Connect();
        ReceiveData();
        msleep(20000);
   }
}


//.main函数

#include <QtCore/QCoreApplication>
#include <QThread>
#include <QDebug>
#include "mytcpserver.h"
#include "mytcpsocket.h"
#include <iostream>
using std::cin;
using std::cout;
using std::endl;

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    char ch;
    cin >> ch;
   MyTcpSocket client;
    MyTcpServer server;
   if(ch == 's'){
        server.Start();
    }else{
       client.Start();
       while(1){
            client.SendData("1234567890");
        }
   }
   return a.exec();
}


问题1:服务器端的定时器不起作用,不知为什么?
问题2:不知道为什么程序经常会崩溃,求帮忙查看崩在哪了?

离线tylan

只看该作者 1楼 发表于: 2015-08-08
这代码弄成这样,你让谁看啊?
离线clannadzy

只看该作者 2楼 发表于: 2015-08-08
把格式弄弄,不让我猜没人想看啊
离线tylan

只看该作者 3楼 发表于: 2015-08-10
1、你的run服务器类中的run函数的while死循环将定时器Timer阻塞了,也就是Timer没有得到运行的机会。
2、我不明白楼主的做法的是,同样在run函数中,如果你的AcceptSocket()函数没有获取到连接,那
CreateThread()和ReceiveData()函数执行的意义在哪里呢?

只看该作者 4楼 发表于: 2015-08-11
回 tylan 的帖子
tylan:1、你的run服务器类中的run函数的while死循环将定时器Timer阻塞了,也就是Timer没有得到运行的机会。
2、我不明白楼主的做法的是,同样在run函数中,如果你的AcceptSocket()函数没有获取到连接,那
CreateThread()和ReceiveData()函数执行的意义在哪里呢? (2015-08-10 09:36) 

回复1:那怎么样才能让Timer有机会执行呢?  回复2:这块逻辑需要改一下,但这不会影响到功能
离线tylan

只看该作者 5楼 发表于: 2015-08-11
回 菜鸟学编程 的帖子
菜鸟学编程:回复1:那怎么样才能让Timer有机会执行呢?  回复2:这块逻辑需要改一下,但这不会影响到功能 (2015-08-11 07:11) 

你的死循环会阻塞Timer定时器,导致Timer无法取得事件。
离线tylan

只看该作者 6楼 发表于: 2015-08-11
回 菜鸟学编程 的帖子
菜鸟学编程:回复1:那怎么样才能让Timer有机会执行呢?  回复2:这块逻辑需要改一下,但这不会影响到功能 (2015-08-11 07:11) 

你如果使用多线程的方式构建服务器程序,那么就用多线程的程序去处理的数据,就不要用Timer了。

只看该作者 7楼 发表于: 2015-08-13
回 tylan 的帖子
tylan:你如果使用多线程的方式构建服务器程序,那么就用多线程的程序去处理的数据,就不要用Timer了。 (2015-08-11 09:07) 

套接字不能在多个线程中使用,所以才用qtimer
快速回复
限100 字节
 
上一个 下一个