`
java-mans
  • 浏览: 11632586 次
文章分类
社区版块
存档分类
最新评论

qt tcpip通讯程序注意

 
阅读更多

传输时最终序列化成char* data;

注意下面三个问题:

1、字节对齐问题

2、【主机字节序,网络字节序】高地址、低地址问题(即字节存储排序问题)

3、float转4字节问题 memcpy(&intVal,&floatVal,sizeof(int));即可。

windows平台【低地址在前】【高地址在后】

void set_float_to_4byte(floatf,quint16*dest)

{
    quint32 i = 0;

    memcpy(&i, &f, sizeof(quint32));

    //windows [low address][high address]
    dest[0] = (quint16)i; //low
    dest[1] = (quint16)(i >> 16);//hi

}

下面转自网络:

字节存储排序:大端和小端的判别及转换


当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-endian)和小端(little- endian)两个描述。
字节排序按分为大端和小端,概念如下
大端(big endian):低地址存放有效字节
小端(little endian):低地址存放有效字节
现在主流的CPU,intel系列的是采用的little endian的格式存放数据,而motorola系列的CPU采用的是big endian,ARM则同时支持 big和little,网络编程中,TCP/IP统一采用大端方式传送数据,所以有时我们也会把大端方式称之为网络字节序。
特别需要注意的是,C/C++语言编写的程序里数据存储顺序是跟编译平台所在的CPU相关的,而 JAVA编写的程序则唯一采用big endian方式来存储数据。这里我就只讨论C/C++语言的情况。


1.大端和小端的方式及判断
举个例子说明,我的机子是32位windows的系统,处理器是AMD的。对于一个int型数0x12345678,为方便说明,这里采用16进制表示。这个数在不同字节顺序存储的CPU中储存顺序如下:
0x12345678 16进制,两个数就是一字节
高有效字节——>低有效字节: 12 34 56 78
低地址位 高低址位
大端: 12 34 56 78
小端: 78 56 34 12
下面验证下本机CPU属于哪种字节存储顺序。代码如下:

test()

{
quint32i=0x12345678;

    qDebug()<<QString::number(i)<<QString::number(i).toAscii().toHex();
    quint8 *p = (quint8*)&i; //将i的地址传给数组指针p,实际上p指向的地址是i在内存中存储的第一个字节,大端就是0x12,小端就是0x78
    if((*p==0x78)&&(*(p+1)==0x56))
        qDebug()<<str2zh("小端"); //windows
    else if((*p==0x12)&&(*(p+1)==0x34))
        qDebug()<<str2zh("大端");
    else
        qDebug()<<str2zh("这是神马字节顺序呢?");
}

调试显示时小端,我用的机子字节存储为小端方式。


2.大端和小端的字节转换
当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序(即大端方式)后再进行传输。此外用C/C++在小端方式的机器上编写的程序与java程序互通时也要进行大端和小端的转换。
这里所谓转换就是改变字节的排序,使交互时数据保持一致。举一个例子,还是16进制表示的数0x12345678,在小端机器上排序为0x78563412,当内存中这样的数传输时,在大端方式下就是0x78563412这个值,与原值不同,要想与原值相同,在传输前,在大端方式下就该是0x12345678,这时原数在内存中为0x12345678,即将原数据0x12345678在内存存储序列为0x12345678,也就是要转换成大端方式。
要传输值:12 34 56 78
不转换时,小端:78 56 34 12
转换为大端:12 34 56 78
根据上面的大端和小端字节排序,可以方便的用移位运算完成转换功能。从小端转到大端代码如下:
#include <iostream>

using namespace std;

typedef unsigned int UINT;
typedef unsigned char UCHAR;

int main()
{
UINT i=0x12345678;
cout<<hex<<i<<endl;
UCHAR *p = (UCHAR*)&i;
UINT num,num1,num2,num3,num4;
num1=(UINT)(*p)<<24;
num2=((UINT)*(p+1))<<16;
num3=((UINT)*(p+2))<<8;
num4=((UINT)*(p+3));
num=num1+num2+num3+num4;

cout<<"num1:"<<hex<<num1<<endl; //看num1的16进制表示,下同
cout<<"num2:"<<hex<<num2<<endl;
cout<<"num3:"<<hex<<num3<<endl;
cout<<"num4:"<<hex<<num4<<endl;
cout<<"num:"<<hex<<num<<endl;

unsigned char *q = (unsigned char*)&num;
if((*q==0x78)&(*(q+1)==0x56))
cout<<"小端"<<endl;
else if((*q==0x12)&(*(q+1)==0x34))
cout<<"大端"<<endl;
else
cout<<"这是神马字节顺序呢?";
return 0;
}
至于说(UINT)(*p)为什么要移24位,其实是很好理解的,将0x00000012变成0x12000000,不就是向左移24位吗。
当然,向上面这样写时为了方便理解,可以更简单的写一个函数用于完成上面的转换功能,函数如下:
UINT EndianConvertLToB(UINT InputNum) {
UCHAR *p = (UCHAR*)&InputNum;
return(((UINT)*p<<24)+((UINT)*(p+1)<<16)+
((UINT)*(p+2)<<8)+(UINT)*(p+3));
}
同样的原理适用于大端转小端,但是大端转小端时移位有差别,函数如下:
UINT EndianConvertBToL(UINT InputNum) {
UCHAR *p = (UCHAR*)&InputNum;
return(((UINT)*p)+((UINT)*(p+1)<<8)+
((UINT)*(p+2)<<16)+(UINT)*(p+3)<<24);
}

分享到:
评论

相关推荐

    Qt的TcpIp客户端和服务端程序

    本项目"Qt的TcpIp客户端和服务端程序"正是基于Qt库实现的网络通信示例,旨在帮助学习者理解和应用Qt的网络功能。 首先,我们要理解TCP/IP协议族的基本概念。TCP(传输控制协议)是一种面向连接的、可靠的、基于字节...

    Qt的Tcpip协议传输案例(有收发程序)

    Qt是一个跨平台的C++应用程序开发框架,它提供了一系列的API来支持TCP/IP通信。本教程将通过介绍Qt中的TCP/IP协议传输案例,帮助初学者理解和实践网络编程。 首先,TCP(Transmission Control Protocol)是一种面向...

    QT实现TCP/IP间的数据通信传输TCPIP.zip

    在"QT实现TCP/IP间的数据通信传输TCPIP.zip"这个压缩包中,包含的是一个使用QT库实现TCP/IP通信的示例项目。这个DEMO演示了如何在服务端和客户端之间通过TCP/IP协议进行文件传输。 首先,我们要理解TCP/IP协议族是...

    TCP通信Qt源码

    本篇将深入探讨“TCP通信Qt源码”的相关知识点,主要涉及客户端、服务器、发送文件以及发送消息。 首先,TCP(Transmission Control Protocol)是一种面向连接的、可靠的传输协议,它通过三次握手建立连接,并在...

    QT实现TcpIP服务器和客户端.rar

    同时,注意线程安全问题,如果需要在多个线程中处理网络通信,可以考虑使用Qt的并发框架如`QThread`或者`QtConcurrent`。 此外,对于TCP通信中的异常处理和错误报告也很重要,例如网络中断、超时等问题。你可以利用...

    qttext_QTTCP_TCPIP_

    "qttext_QTTCP_TCPIP_"这个标题表明我们将探讨的是使用QT进行TCP通信的实现,主要关注服务端和客户端的编程。 在QT中,QNetwork模块提供了TCP通信的支持。QTCPSocket类是用于TCP通信的基础,它可以用来创建TCP...

    QT中利用TCP协议实现了一个多线程的文件互传系统

    在QT中,我们可以使用QTcpSocket类来实现TCP通信。QTcpSocket提供了打开、关闭、连接、读写等方法,方便地进行网络通信。 多线程是提高应用程序性能的重要手段,尤其在处理并发任务时。在QT中,QThread类提供了对多...

    基于QT的数据通信传输TCPIP.rar

    QT框架是一个跨平台的应用程序开发框架,它提供了丰富的库支持,包括用于TCP/IP通信的功能。本项目“基于QT的数据通信传输TCPIP.rar”旨在演示如何使用QT库中的功能来实现C++代码进行数据通信,包括文件、大数组以及...

    Qt TCP编程之服务器端程序

    在本文中,我们将深入探讨如何使用Qt库进行TCP编程,特别是构建服务器端程序。Qt是一个功能强大的跨平台应用程序开发框架,支持多种操作系统,包括Windows、Linux、macOS等。TCP(传输控制协议)是一种面向连接的、...

    Qt TCP/UDP通讯封装示例

    在本文中,我们将深入探讨如何使用Qt库进行TCP和UDP通信的封装,以及如何实现四种不同的通信模式:TCP客户端、TCP服务器、UDP客户端和UDP服务器。Qt是一个强大的跨平台应用程序开发框架,它提供了丰富的网络编程接口...

    qtTCP多线程服务的例子

    QTCP多线程服务是Qt库中用于网络通信的一个重要应用,它允许开发人员构建高效且可扩展的服务器应用程序。这个例子是一个使用Qt的TCP服务器,通过多线程技术来处理客户端连接,确保在规定时间内(3秒)完成数据交换。...

    QT 局域网聊天 TCPIP协议

    QT库是一种跨平台的C++应用开发框架,广泛用于创建图形用户界面和其他应用程序。在局域网聊天应用中,QT可以作为一个强大的工具,因为它提供了丰富的网络编程接口,使得开发者能够轻松实现TCP/IP通信协议,从而实现...

    QT中tcp数据传输的事例程序

    QT是Qt Company开发的一种跨平台应用程序开发框架,广泛应用于GUI(图形用户界面)设计和网络编程。在本案例中,我们将深入探讨如何在QT中利用TCP(Transmission Control Protocol)进行稳定安全的数据传输,特别是...

    三种QT的进程间通信源代码(TCPIP、ShareMemory和Process)

    QT框架是Qt公司开发的一种跨平台的C++应用程序开发框架,广泛应用于图形用户界面和系统编程。在QT中,进程间通信(IPC, Inter-Process Communication)是实现不同进程之间数据交换的重要技术,尤其在多模块、分布式...

    基于c++语言使用QT进行数据通信传输.rar

    本项目“基于C++语言使用QT进行数据通信传输”着重于利用QT框架进行TCP/IP通信,这对于理解网络编程的基本原理以及如何在C++环境中实现它非常有帮助。 首先,QT是一个跨平台的应用程序开发框架,由Qt Company提供,...

    QT的TCP一个服务端连接多个客户端

    QT是Qt Company开发的一种跨平台应用程序开发框架,广泛用于创建桌面、移动和嵌入式系统的图形用户界面。在本文中,我们将深入探讨如何使用QT来实现一个TCP服务器,该服务器可以同时连接并处理多个客户端的请求。 ...

    基于tcpip的Qt聊天室.zip

    Qt是一个跨平台的应用程序开发框架,广泛应用于桌面、移动以及嵌入式设备上。C++是其主要的编程语言,提供丰富的功能和高性能。 首先,TCP/IP(传输控制协议/互联网协议)是互联网上的通信标准,它定义了数据在网络...

    myTcpTools5.7_20180426.rar

    而QTTCPIP则是Qt框架下实现TCP/IP通信的一种强大工具。本文将深入探讨基于"myTcpTools5.7_20180426.rar"的QTTCPIP技术,帮助开发者理解其工作原理,并提供实践指导。 首先,"myTcpTools5.7"是基于Qt5.7版本开发的一...

    Qt5的TcpDemo

    在本篇中,我们将深入探讨Qt5框架下的TCP/IP网络编程,主要基于提供的"Qt on android第十章网络编程TcpIp 简单demo"。Qt5是一个强大的跨平台应用程序开发框架,广泛应用于桌面、移动以及嵌入式系统,包括Android平台...

    TCPIP_Demo.zip

    在IT行业中,TCP/IP协议族是...这个"TCPIP_Demo"项目不仅展示了TCP/IP通信的基本原理,还涵盖了Qt Creator在实现网络应用程序时的常用技术和实践方法,对于学习网络编程和Qt应用开发的开发者来说是一个很好的实践案例。

Global site tag (gtag.js) - Google Analytics