TCP
        TCP是一个基于流的协议。对于应用程序,数据表现为一个长长的流,而不是一个大大的平面文件。基于TCP的高层协议通常是基于行的或者基于块的。
          ●、基于行的协议把数据作为一行文本进行传输,每行都以一个换行符结尾。
          ●、基于块的协议把数据作为二进制块进行传输,每块是由一个size大小字段和紧跟它的一个size字节的数据组成。
        QTcpSocket通过器父类QAbstractSocket继承了QIODevice,因此他可以通过使用QTextStream和QDataStream来进行读取和写入。
        QTcpServer类在服务器端处理来自TCP客户端连接数据,需要注意的是,该类直接继承于QObject基类,而不是QAbstractSocket抽象套接字类。
 
一 QTcpServer
#ifndef VXMAINWINDOW_H
#define VXMAINWINDOW_H
#include 
#include 
#include
class QPushButton;
class QTextEdit;
class CVxMainWindow : public QWidget
{
 Q_OBJECT
public:
 CVxMainWindow(QWidget *parent = NULL);
 ~CVxMainWindow();
protected:
 void resizeEvent(QResizeEvent *);
private slots:
 void Btn_ListenClickedSlot();
 void Btn_StopListenClickedSlot();
 void newConnectionSlot();
 void dataReceived();
private:
 QTcpServer *m_pServer;
 QTcpSocket *m_pSocket;
 QPushButton *m_pBtn_Listen;
 QPushButton *m_pBtn_StopListen;
 QTextEdit   *m_pEdt_Info;
};
#endif // VXMAINWINDOW_H
 
#include "VxMainWindow.h"
#include
CVxMainWindow::CVxMainWindow(QWidget *parent)
 : QWidget(parent)
{
 m_pBtn_Listen     = new QPushButton(QObject::tr("开始监听"), this);
 m_pBtn_StopListen = new QPushButton(QObject::tr("停止监听"), this);
 m_pEdt_Info = new QTextEdit(this);
 m_pServer = new QTcpServer(this);
 
 connect(m_pBtn_Listen,     SIGNAL(clicked()), this, SLOT(Btn_ListenClickedSlot()));
 connect(m_pBtn_StopListen, SIGNAL(clicked()), this, SLOT(Btn_StopListenClickedSlot()));
 connect(m_pServer, SIGNAL(newConnection()), this, SLOT(newConnectionSlot()));
}
CVxMainWindow::~CVxMainWindow()
{
}
void CVxMainWindow::resizeEvent(QResizeEvent *)
{
 m_pBtn_Listen->setGeometry(10, 5, 80, 20);
 m_pBtn_StopListen->setGeometry(100, 5, 80, 20);
 m_pEdt_Info->setGeometry(0, 30, width(), height() - 30);
}
void CVxMainWindow::Btn_ListenClickedSlot()
{
 if (!m_pServer->isListening())
 {
  if (m_pServer->listen(QHostAddress::Any, 8080)) 
  {
   m_pEdt_Info->append(QObject::tr("打开监听端口成功!"));
  }
  else
  {
   m_pEdt_Info->append(QObject::tr("打开监听端口失败!"));
  }
 }
 else
 {
  m_pEdt_Info->append(QObject::tr("正在监听中...!"));
 }
}
void CVxMainWindow::Btn_StopListenClickedSlot()
{
 if (m_pServer->isListening())
 {
  m_pServer->close();
  m_pEdt_Info->append(QObject::tr("停止监听!"));
 }
}
void CVxMainWindow::newConnectionSlot()
{
 m_pEdt_Info->append(QObject::tr("有新客户端连接到服务器"));
 m_pSocket = m_pServer->nextPendingConnection();
 connect(m_pSocket, SIGNAL(disconnected()), m_pSocket, SLOT(deleteLater()));
 connect(m_pSocket, SIGNAL(readyRead()),this, SLOT(dataReceived()));
 int length = 0;
 QString vMsgStr = QObject::tr("Welcome");
 if((length=m_pSocket->write(vMsgStr.toLatin1(),vMsgStr.length()))!=vMsgStr.length())
 {
 }
}
void CVxMainWindow::dataReceived()
{
 while(m_pSocket->bytesAvailable())
 {       
  QByteArray vTemp;
  vTemp = m_pSocket->readLine();  
  QString vTempStr(vTemp);
  m_pEdt_Info->append(vTempStr);
  int length = 0;
  QString vMsgStr = QObject::tr("回复:") + vTempStr;
  if((length=m_pSocket->write(vMsgStr.toLatin1(),vMsgStr.length()))!=vMsgStr.length())
  {
  }
 }
}
 
二 QTcpSocket
 
 
#ifndef VXMAINWINDOW_H
#define VXMAINWINDOW_H
#include 
#include 
#include
class QPushButton;
class QTextEdit;
class QLineEdit;
class CVxMainWindow : public QWidget
{
 Q_OBJECT
public:
 CVxMainWindow(QWidget *parent = NULL);
 ~CVxMainWindow();
protected:
 void resizeEvent(QResizeEvent *);
private slots:
 void Btn_ConnectClickedSlot();
 void Btn_DisConnectClickedSlot();
 void Btn_SendClickedSlot();
 void connectedSlot();
 void disconnectedSlot();
 void dataReceived();
 void displayError(QAbstractSocket::SocketError);
private:
 QTcpSocket *m_pSocket;
 QHostAddress m_HostAddress;
 QPushButton *m_pBtn_Connect;
 QPushButton *m_pBtn_DisConnect;
 QTextEdit   *m_pEdt_Info;
 QLineEdit   *m_pEdt_Send;
 QPushButton *m_pBtn_Send;
};
#endif // VXMAINWINDOW_H
 
#include "VxMainWindow.h"
#include
CVxMainWindow::CVxMainWindow(QWidget *parent)
 : QWidget(parent)
{
 m_pBtn_Connect    = new QPushButton(QObject::tr("连接服务器"), this);
 m_pBtn_DisConnect = new QPushButton(QObject::tr("断开连接"), this);
 m_pEdt_Send       = new QLineEdit(this);
 m_pBtn_Send       = new QPushButton(QObject::tr("发送"), this);
 m_pEdt_Info = new QTextEdit(this);
 m_pSocket = new QTcpSocket(this);
 connect(m_pBtn_Connect,    SIGNAL(clicked()), this, SLOT(Btn_ConnectClickedSlot()));
 connect(m_pBtn_DisConnect, SIGNAL(clicked()), this, SLOT(Btn_DisConnectClickedSlot()));
 connect(m_pBtn_Send,       SIGNAL(clicked()), this, SLOT(Btn_SendClickedSlot()));
 connect(m_pSocket, SIGNAL(connected()), this, SLOT(connectedSlot()));
 connect(m_pSocket, SIGNAL(disconnected()), this, SLOT(disconnectedSlot()));
 connect(m_pSocket, SIGNAL(readyRead()),this, SLOT(dataReceived()));
 connect(m_pSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
}
CVxMainWindow::~CVxMainWindow()
{
}
void CVxMainWindow::resizeEvent(QResizeEvent *)
{
 m_pBtn_Connect->setGeometry(10, 5, 80, 20);
 m_pBtn_DisConnect->setGeometry(100, 5, 80, 20);
 m_pEdt_Send->setGeometry(10, 30, 150, 20);
 m_pBtn_Send->setGeometry(170, 30, 80, 20);
 m_pEdt_Info->setGeometry(0, 60, width(), height() - 60);
}
void CVxMainWindow::Btn_ConnectClickedSlot()
{
 m_HostAddress.setAddress(QObject::tr("127.0.0.1"));
 m_pSocket->connectToHost(m_HostAddress, 8080);
}
void CVxMainWindow::Btn_DisConnectClickedSlot()
{
 m_pSocket->disconnectFromHost();
}
void CVxMainWindow::Btn_SendClickedSlot()
{
 int length = 0;
 QString vMsgStr = m_pEdt_Send->text();
 if((length = m_pSocket->write(vMsgStr.toLatin1(),vMsgStr.length())) != vMsgStr.length())
 {
  m_pEdt_Info->append(QObject::tr("发送信息失败:") + vMsgStr);
 }
}
void CVxMainWindow::connectedSlot()
{
 m_pEdt_Info->append(QObject::tr("成功连接到服务器!"));
}
void CVxMainWindow::disconnectedSlot()
{
 m_pEdt_Info->append(QObject::tr("断开与服务器的连接!"));
}
void CVxMainWindow::dataReceived()
{
 while(m_pSocket->bytesAvailable())
 {       
  QString vTemp;
  vTemp = m_pSocket->readLine();          
  m_pEdt_Info->append(vTemp);
 }
}
void CVxMainWindow::displayError(QAbstractSocket::SocketError)
{
}
 
以上代码在发送和接受串中带中文时会出现乱码,下面提供另外的发送和接受方法:
1 发送:
void XXX()
{
 // 用于暂存我们要发送的数据
 QByteArray block; 
 // 使用数据流写入数据
 QDataStream out(&block,QIODevice::WriteOnly);
 // 设置数据流的版本,客户端和服务器端使用的版本要相同
 out.setVersion(QDataStream::Qt_4_7);
 out<<(quint16) 0;
 out<<qobject::tr("您好啊!");
 out.device()->seek(0);
 out<<(quint16)(block.size() - sizeof(quint16));
 m_pSocket->write(block);
}
2 接受:
void CVxMainWindow::dataReceived()
{
 QString vTempStr;  
 quint16 blockSize = 0;
 QDataStream in(m_pSocket);
 // 设置数据流版本,这里要和服务器端相同
 in.setVersion(QDataStream::Qt_4_7);
 // 如果是刚开始接收数据
 if(blockSize == 0) 
 {
  //判断接收的数据是否有两字节,也就是文件的大小信息
  //如果有则保存到blockSize变量中,没有则返回,继续接收数据
  if(m_pSocket->bytesAvailable() < (int)sizeof(quint16)) return;
  in >> blockSize;
 }
 // 如果没有得到全部的数据,则返回,继续接收数据
 if(m_pSocket->bytesAvailable() < blockSize) return;
 in >> vTempStr;
 m_pEdt_Info->append(vTempStr);
}
http://blog.chinaunix.net/uid-20718335-id-1993063.html

QTcpServer与QTcpSocket通讯的更多相关文章

  1. qt QTcpServer与QTcpSocket通讯

    分类: C/C++ TCP        TCP是一个基于流的协议.对于应用程序,数据表现为一个长长的流,而不是一个大大的平面文件.基于TCP的高层协议通常是基于行的或者基于块的.          ...

  2. Qt网络编程QTcpServer和QTcpSocket的理解

    前一段时间通过调试Qt源码,大致了解了Qt的事件机制.信号槽机制.毕竟能力和时间有限.有些地方理解的并不是很清楚. 开发环境:Linux((fedora 17),Qt版本(qt-everywhere- ...

  3. C/C++学习)22.QTcpServer、QTcpSocket、QUdpSocket使用

    一.TCP/UDP通信在Qt中的实现过程: 废话不说,首先下面是Qt中TCP/UDP的实现图解: 1.Qt下TCP通信详解: 针对上图进行简单的说明:         QTcpServer用来创建服务 ...

  4. 基于QTcpSocket和QTcpServer的Tcp通讯以及QDataStream序列化数据

    最近要在QT下开发Tcp通讯,发送序列化数据以便于接收. 这里涉及到几个问题: 1.QTcpSocket.QTcpServer的通讯 2.QDataStream序列化数据 多的不说,直接上干货!!! ...

  5. QT5 网络通讯

    QT5 TCP网络通讯 服务器与客户端建立连接listen() - connectToHost();  触发newPendingConnect信号 实时数据通讯write(); read();  触发 ...

  6. QT5在VS2013中找不到QtNetwork或QTcpSocket或QTcpSocket等头文件

    一.首先是要有相关的库文件 方法一:手动添加库文件Qt5Networkd.lib 对项目进行右键,找到相关的属性,然后查看Linker中input部分的红色选项中是否含有Qt5Networkd.lib ...

  7. 5.关于QT中的网络编程,QTcpSocket,QUdpSocket

     1 新建一个项目:TCPServer.pro A  修改TCPServer.pro,注意:如果是想使用网络库,需要加上network SOURCES += \ TcpServer.cpp \ T ...

  8. QTcpSocket使用过程中的一些问题记录

    目前,在将原来C的socket通讯改为使用Qt类库QTcpSocket通讯,在修改过程中遇到不少问题,在此将问题一并记录,以备后面使用. 采用的通讯方式:QTimer定时器.QThread多线程和QT ...

  9. Qt NetWork即时通讯网络聊天室(基于TCP)

    本文使用QT的网络模块来创建一个网络聊天室程序,主要包括以下功能: 1.基于TCP的可靠连接(QTcpServer.QTcpSocket) 2.一个服务器,多个客户端 3.服务器接收到某个客户端的请求 ...

随机推荐

  1. MySQL参数文件位置

    对于linux/unix: mysql --help|grep my.cnf   /etc/my.cnf, /etc/mysql/my.cnf, /usr/local/etc/my.cnf, ~/.m ...

  2. 微信测试号开发之九 微信网页授权:页面获取用户openid

    原文链接:https://blog.csdn.net/qq_37936542/article/details/78981369 一:配置接口 注意:这里填写的是域名(是一个字符串),而不是URL,因此 ...

  3. Uncaught SyntaxError: Unexpected end of input 解决办法

    Unexpected end of input  的英文意思是"意外的终止输入" 他通常表示我们浏览器在读取我们的js代码时,碰到了不可预知的错误,导致浏览器 无语进行下面的读取 ...

  4. Android有用的任务管理器—tractor

    在平时的android开发工作中,我们常常须要运行耗时操作,有时为了用户体验还须要显示个等待框,我之前的做法都是开一个线程,然后用handler发消息进行显示和关闭等待框以及相关的ui操作.假设任务比 ...

  5. 小强的HTML5移动开发之路(21)—— PhoneGap

    一.PhoneGap是什么 PhoneGap 是一个用基于 HTML,CSS 和 JavaScript 的,创建移动跨平台移动应用程序的快速开发框架.它使开发者能够利用 iPhone,Android, ...

  6. 浅谈CAS(Compare and Swap) 原理

    浅谈CAS原理java并发编程也研究了一段时间了,对CAS的原理总是不太理解,今天再研究了一下,记录一些自己的理解.    说到CAS,再java中的某些情况下,甚至jdk1.5以后的大多数情况,并发 ...

  7. 大型项目linux自动化版本发布脚本(shell)之tomcat、nginx服务脚本

    开发十年,就只剩下这套Java开发体系了 >>>   最近,又临近博主所负责的一个大型项目的发版了.之前有提到过,该项目涉及到30-40台服务器的发版.且项目客户规定发版需在晚上10 ...

  8. Cordova-Android-Android target:not installed

    原文:Cordova-Android-Android target:not installed 运行cordova requirements检查是否具备使用 Cordova 开发/运行 Android ...

  9. maven 依赖(依赖范围,聚合,继承等)

    目录: 1.什么是依赖? 2.依赖的管理:依赖的范围与传递,依赖的排除,依赖的原则(maven对依赖冲突的处理原则) 3.依赖的版本管理 4.继承与聚合 1.什么是依赖? 简单的讲,当jar包A需要j ...

  10. Spring实战5-基于Spring构建Web应用

    主要内容 将web请求映射到Spring控制器 绑定form参数 验证表单提交的参数 写在前面:关于Java Web,首先推荐一篇文章——写给java web一年左右工作经验的人,这篇文章的作者用精练 ...