使用Socket传输对象

在使用QT网络通信时一直是简单的发送数据--接收数据,常见的就是发送一个字符串/字节流,然后根据这个字符串/字节流提取出有用的信息。 这样在不是很复杂的通信中可以满足实际需要。但也有弊端,就是每次写网络通信时都是口头约定一个协议,让发送方与接收方都满足这个协议才可以进行正常通信。 这样如果我每次写这样的程序,我都要首先规定好一个的通讯协议,然后再编写相应的代码。

那么如何传输更复杂的数据呢,而且可以不用上述的口头协议?

在JAVA,C#中都有对对象序列化的概念,QT里也有,利用将对象序列化传输可以对更加方便地传输我们构造的一些复杂对象数据。

QT序列化

The QDataStream allows you to serialize some of the Qt data types. The table below lists the data types that QDataStream can serialize and how they are represented. The format described below is version 12. It is always best to cast integers to a Qt integer type, such as qint16 or quint32, when reading and writing. This ensures that you always know exactly what size integers you are reading and writing, no matter what the underlying platform and architecture the application happens to be running on.

序列化就是将一个类变成一系列的字节,利用反序列化也可以将这些字节构造出原始的这个类。这些字节可以直接存储在硬盘上,当然也可以通过网络发送出去。利用以上这些特点我们就可以开始进行一些有意思的网络通信。

当然也不是所有的类都能满足可序列化,QT 对满足序列化的类进行了说明

bool
    boolean
qint8
    signed byte
qint16
    signed 16-bit integer
qint32
    signed 32-bit integer
qint64
    signed 64-bit integer
quint8
    unsigned byte
quint16
    unsigned 16-bit integer
quint32
    unsigned 32-bit integer
quint64
    unsigned 64-bit integer
float
    32-bit floating point number using the standard IEEE 754 format
double
    64-bit floating point number using the standard IEEE 754 format
const char *
    The string length (quint32)
    The string bytes, excluding the terminating 0
QBitArray
    The array size (quint32)
    The array bits, i.e. (size + 7)/8 bytes
QBrush
    The brush style (quint8)
    The brush color (QColor)
    If style is CustomPattern, the brush pixmap (QPixmap)
QByteArray
    If the byte array is null: 0xFFFFFFFF (quint32)
    Otherwise: the array size (quint32) followed by the array bytes, i.e. size bytes
QColor
    Color spec (qint8)
    Alpha value (quint16)
    Red value (quint16)
    Green value (quint16)
    Blue value (quint16)
    Pad value (quint16)
    QCursor
    Shape ID (qint16)
    If shape is BitmapCursor: The bitmap (QPixmap), mask (QPixmap), and hot spot (QPoint)
QDate
    Julian day (quint32)
QDateTime
    Date (QDate)
    Time (QTime)
    0 for Qt::LocalTime, 1 for Qt::UTC (quint8)
QEasingCurve
    type (quint8)
    func (quint64)
    hasConfig (bool)
    If hasConfig is true then these fields follow:
    list
    period (double)
    amplitude (double)
    overshoot (double)
QFont
    The family (QString)
    The point size (qint16)
    The style hint (quint8)
    The char set (quint8)
    The weight (quint8)
    The font bits (quint8)
QHash<Key, T>
    The number of items (quint32)
    For all items, the key (Key) and value (T)
QIcon
    The number of pixmap entries (quint32)
    For all pixmap entries:
    The pixmap (QPixmap)
    The file name (QString)
    The pixmap size (QSize)
    The mode (quint32)
    The state (quint32)
QImage
    If the image is null a "null image" marker is saved; otherwise   the image is saved in PNG or BMP format (depending on the stream version). If you want control of the format, stream the image into a QBuffer (using QImageIO) and stream that.
QKeySequence
    A QList<int>, where each integer is a key in the key sequence
QLinkedList<T>
    The number of items (quint32)
    The items (T)
QList<T>
    The number of items (quint32)
    The items (T)
QMap<Key, T>
    The number of items (quint32)
    For all items, the key (Key) and value (T)
QMatrix(obsolete)
    m11 (double)
    m12 (double)
    m21 (double)
    m22 (double)
    dx (double)
    dy (double)
QMatrix4x4
    m11 (double)
    m12 (double)
    m13 (double)
    m14 (double)
    m21 (double)
    m22 (double)
    m23 (double)
    m24 (double)
    m31 (double)
    m32 (double)
    m33 (double)
    m34 (double)
    m41 (double)
    m42 (double)
    m43 (double)
    m44 (double)
QPair<T1, T2>
    first (T1)
    second (T2)
QPalette	The disabled, active, and inactive color groups, each of which consists of the following:
    foreground (QBrush)
    button (QBrush)
    light (QBrush)
    midlight (QBrush)
    dark (QBrush)
    mid (QBrush)
    text (QBrush)
    brightText (QBrush)
    buttonText (QBrush)
    base (QBrush)
    background (QBrush)
    shadow (QBrush)
    highlight (QBrush)
    highlightedText (QBrush)
    link (QBrush)
    linkVisited (QBrush)
QPen
    The pen styles (quint8)
    The pen width (quint16)
    The pen color (QColor)
QPicture
    The size of the picture data (quint32)
    The raw bytes of picture data (char)
QPixmap
    Save it as a PNG image.
QPoint
    The x coordinate (qint32)
    The y coordinate (qint32)
QQuaternion
    The scalar component (double)
    The x coordinate (double)
    The y coordinate (double)
    The z coordinate (double)
QRect
    left (qint32)
    top (qint32)
    right (qint32)
    bottom (qint32)
QRegExp
    The regexp pattern (QString)
    Case sensitivity (quint8)
    Regular expression syntax (quint8)
    Minimal matching (quint8)
QRegion
    The size of the data, i.e. 8 + 16 * (number of rectangles)    (quint32)
    10 (qint32)
    The number of rectangles (quint32)
    The rectangles in sequential order (QRect)
QSize
    width (qint32)
    height (qint32)
QString
    If the string is null: 0xFFFFFFFF (quint32)
    Otherwise: The string length in bytes (quint32) followed by the data in UTF-16
QTime
    Milliseconds since midnight (quint32)
QTransform
    m11 (double)
    m12 (double)
    m13 (double)
    m21 (double)
    m22 (double)
    m23 (double)
    m31 (double)
    m32 (double)
    m33 (double)
QUrl
    Holds an URL (QString)
QVariant
    The type of the data (quint32)
    The null flag (qint8)
    The data of the specified type
QVector2D
    the x coordinate (double)
    the y coordinate (double)
QVector3D
    the x coordinate (double)
    the y coordinate (double)
    the z coordinate (double)
QVector4D
    the x coordinate (double)
    the y coordinate (double)
    the z coordinate (double)
    the w coordinate (double)
QVector<T>
    The number of items (quint32)
    The items (T)

上面这些已经足够强大了,试想一下,你在本地构造一个QList/QImage,能够完整地传输到对方,而且不用编写相关的构造代码就可以将对象传输过去能够省去多少力气。

今天写了一个DEMO演示了一下,感觉效果还不错。

首先构造一个自己的可序列化的类

class DataPackage
{
public:
    QString label_1;
    QString label_2;
    friend QDataStream& operator >>(QDataStream& so,DataPackage& de);
    friend QDataStream& operator <<(QDataStream& de,DataPackage& so);
};

然后重载操作符

QDataStream& operator>> (QDataStream& so,DataPackage& de)
{
    return so>>de.label_1>>de.label_2;
}
QDataStream& operator<< (QDataStream& de,DataPackage& so)
{
    return de<<so.label_1<<so.label_2;
}

这样发送方发送的时候

void MainWindow::send_button()
{
    if(!this->socketA){
        this->ui->statusBar->showMessage("not a socket",5000);
        return;
    }
    DataPackage package;
    package.label_1=this->ui->A1->text();
    package.label_2=this->ui->A2->text();

    QByteArray by;
    QDataStream ds(&by,QIODevice::WriteOnly);
    ds<<package;
    this->socketA->write(by);
}

接收方接收的时候

void MainWindow::socketB_recv()
{
    QByteArray by= this->socketB->readAll();
    QDataStream ds(&by,QIODevice::ReadOnly);
    DataPackage package;
    ds>>package;
    this->ui->B1->setText(package.label_1);
    this->ui->B2->setText(package.label_2);
}

以上轻松传递一个对象,重载的操作符<<相当与序列化这个对象。>>相当与反序列化对象。这样如果双方写协议的时候只需要构造一个协议包,然后两边分别进行序列化反序列化操作进行通信了,配合QT默认的类型将通信内容更加复杂化,使用更加便捷化。

时间: 2024-10-13 21:33:21

使用Socket传输对象的相关文章

socket传输对象

server public class Server{ private static int port = 8888; private static ServerSocket serverSocket; private static Socket socket; public static void main(String args[]) throws IOException { serverSocket = new ServerSocket(port, 2); socket = serverS

JAVA Socket传输Object(对象)注意的问题

在java中,可以通过socket将一个对象进行传递,通过ObjectOutputStream,ObjectInputStream来进行写入和读取(具体的方法参考http://blog.csdn.net/zyujie/article/details/8243742),但在传递时需要注意以下两点: 1.传递的对象必须实现Serializable标记接口,实现对象的可序列化.如public class Employee implements Serializable 2.发送和接收的对象包名应该保持

unity探索者之socket传输protobuf字节流(一)

近期在做一个棋牌项目,需要用到socket传输protobuf字节流,在网上找了一些博客和文章后发现,没有特别全面的,所以把自己研究的全部源码拿出来和大家分享,因为刚开始做,可能会有不足的地方,欢迎拍砖~~ 这一篇主要是protocol buffer文件的序列化和解析,废话不多说了,直接上干货 1 /// <summary> 2 /// 将消息序列化为二进制的方法 3 /// </summary> 4 /// <param name="model">

Mina使用总结(四)传输对象ObjectSerializationCodecFactory

用mina框架传输对象,对于开发者来说,直接传输对象,而不用自己编写相应的报文转换代码,将大大节省 开发时间. 即使用对象编码解码器 使用ObjectSerializationCodecFactory 服务端 MinaServer.java代码如下 package com.bypay.mina.server; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress;

[C#技术参考]Socket传输结构数据

最近在做一个机器人项目,要实时的接收机器人传回的坐标信息,并在客户端显示当前的地图和机器人的位置.当然坐标的回传是用的Socket,用的是C++的结构体表示的坐标信息.但是C#不能像C++那样很easy的把字节数组byte[]直接的转换成结构,来发送和接收.在C#中要多做一些工作.但是在C或者C++中这是一件很容易的事,只需要一个函数: void *memcpy(void *dest, const void *src, size_t n);//从源src所指的内存地址的起始位置开始拷贝n个字节到

C++ socket 传输不同类型数据的四种方式

使用socket传输组织好的不同类型数据,有四种不同的方式(我知道的嘿嘿): a. 结构体 b. Json序列化 c. 类对象 d. protobuf 下面逐一整理一下,方便以后进行项目开发. 1. 使用结构体 假设需要传送的结构体如下: struct person { char name[20]; // 注意:CPU访问内存的时候,对访问地址有对齐的要求,一般为2的幂次方.所以,有的数据被填充,以满足对齐要求. int age; float high; }; 可在发送数据的地方对数据进行处理,

Netty 4 传输对象

对于Netty在这里就不做过多介绍了,详情咨询http://netty.io/wiki/user-guide-for-4.x.html 我们在使用netty的过程中肯定会遇到传输对象的情况,Netty4通过ObjectEncoder和ObjectDecoder来支持. 首先我们定义一个User对象,一定要实现Serializable接口: import java.io.Serializable; /** * User: hupeng * Date: 14-6-3 * Time: 上午1:31 *

C# Socket传输大文件

1.基础类TransferFiles,client和server都需要 using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; using System.Windows.Forms; namespace Server { public class TransferFiles { public static int SendData(

巧用Android网络通信技术,在网络上直接传输对象

本文首发于CSDN博客,转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/8967080 要做一个优秀的Android应用,使用到网络通信技术是必不可少的,很难想象一款没有网络交互的软件最终能发展得多成功.那么我们来看一下,一般Android应用程序里都是怎么实现网络交互的,这里拿一个Boook对象为例: 如上图所示,首先在手机端生成一个Book对象,里面包含书名.作者.价格等数据.为了要将这些数据发送到服务器端,我们要从Book对