基于gec6818的QT病房系统

目录

前言

一、低频RFID卡的读取

1、模块引脚说明:

2、模块工作参数:

3、模块工作原理如下:

4、模块输出格式如下:

5、读取卡号代码如下:

二、GY39模块

1、模块引脚说明:

2、通信协议

3、相关代码

三、MQ2烟雾传感器

1、模块引脚说明:

2、通信协议

3、代码如下

四、服务器TCP初始化

五、客户端TCP欻化

总结


前言

经过几个星期对QT系统的学习,完成了一个关于QT的项目,本项目用到的模块有gec6818开发板,一个低频RFID,一个低频RFID读卡器,gy39,MQ2烟雾传感器。具体功能如下:

1.门禁卡注册功能:
        根据RFID实现用户注册功能,记录一些用户的基本信息,如姓名、电话号码、房间号等。
        在给患者登记(注册)信息的时候,同时录入房卡信息
        房卡信息(房卡ID),由开发板接上RFID读取器读取卡的信息,将读到的卡号发送给服务端,
        完成卡和房间的绑定
        其中要有病人信息表,房间信息表,医生信息表,管理员信息表等

    2.门禁卡丢失注销功能:可以更改门禁卡号,把之前的门禁卡号注销失效。
    
    3.门禁功能:进入病房需要刷卡,卡号识别正确则打开门锁,卡号识别错误则提示出错信息。
    
    4.安防功能:时刻检测房间的温度和烟雾浓度,如果数据异常则触发蜂鸣器报警。

一、低频RFID卡的读取

1、模块引脚说明

1

GND

地(实际要用)

2

VCC

+5v(实际要用)

3

NC

悬空

4

TXD

串口输出(实际要用)

5

HOLD

有效输出

6

XH

串口输入

7

L1

接读卡天线

8

L2

接读卡天线

2、模块工作参数:

电源: 4 -5 V , <50MA

工作频率:125KHZ 土 IKhz

支持卡片:EM4001、4102或兼容的ID卡

读卡距离: < 15CM 距离跟卡和天线大小有关

输出方式:串口 TTL-223电平

读卡方式:刷一次一卡,输出一次卡号

读卡速度: <100MS

工作温度:-10 ~ 75 ℃

模块尺寸: 2.5 * 2.5CM

线圈电感: 3 45uH

3、模块工作原理如下

在模块处于工作状态时(接上电源和天线〉,当卡片靠近读卡器时, 读卡模块与卡片之间通过内部的射频电路和感应天线感应,使读卡模块获得射频ID卡的信号,即完成一次读取,同时,将读到的只读型射频卡号,进而解译逅成为JTLi32格式经输出.此时,只要该卡片丕远离感应区, 就不会再次读卡,当该卡片离开有效的感应区后,才能再次有效读卡,以防重复读卡。

4、模块输出格式如下:

模块是1TL-RS232 ASCII数据输出(串口输出,TFL电平)

9600 bps,n,8,l破特率9600无校验位数81位停止位) (也可以按客户要求输出P

Output Format-Serial Output"

02

10ASCIdata

Checksum

03

02开头,03是结束码

例如:卡片号码为0A003CE2C2,传送的HEX值如下10 ASCII DATA: 30H, 41H, 30H, 30H,33H,43H,45H,32H,43H,32H

0   A   0   0   3   C   E   2   C   2

ChecKsum: (OAH) XOR(OOH)XOR(3CH)XOR(E2H)XOR(C2H)=16H

(XOR:^sS运算)为二迸制数据格式故模块输出完整数据文档如下:

02H, 30H, 41H, 30H, 30H, 33H, 43H, 45H, 32H, 43 H32H, 16H, 03H

5、读取卡号代码如下:

//串口初始化
int   uart1_init()
{

	int   uart1_fd= open("/dev/ttySAC1", O_RDWR);//打开串口1设备文件
	if (uart1_fd == -1)
	{
		perror("open error:");
		return -1;
	}

	struct termios myserial;
	
	memset(&myserial, 0, sizeof (myserial));//清空结构体
	
	myserial.c_cflag |= (CLOCAL | CREAD);//O_RDWR

	//设置控制模式状态,本地连接,接受使能
	//设置 数据位
	myserial.c_cflag &= ~CSIZE;   //清空数据位
	myserial.c_cflag &= ~CRTSCTS; //无硬件流控制
	myserial.c_cflag |= CS8;      //数据位:8

	myserial.c_cflag &= ~CSTOPB;//   //1位停止位
	myserial.c_cflag &= ~PARENB;  //不要校验

	cfsetospeed(&myserial, B9600);  //设置波特率,B9600是定义的宏
	cfsetispeed(&myserial, B9600);
	
	tcflush(uart1_fd, TCIFLUSH);/* 刷新输出队列,清楚正接受的数据 */

	tcsetattr(uart1_fd, TCSANOW, &myserial);/* 改变配置 */
	return   uart1_fd;
}

//16进制转换
int binary(int num)
{
	int i=0,j;
	while(num)
	{
		if(num>=16)
		{
			j=num/16;
			i+=j;
		}
		else
		{
			i+=num;
			break;
		}
		num=num%16;
		i=i*10;	
	}
	return i;
}

int main()
{
	int size=0,i;
	int fd=uart1_init();//串口初始化
	int h=0;
	int l=0;
	long int id=0;

	while(1)
	{
		size=read(fd,buf,13);//柱塞等待,串口接收数据
		if(size==13)//接收到13byte数据
		{
			if(buf[0]!=0x02 || buf[12]!=0x03)//判断开始和结束
			{
				printf("read err\n");
			}
			else//读卡成功
			{
				for(i=5;i<11;i++)//数据位进制转换
				{
					if((buf[i]-'0')>=10)//10进制转16进制
					{
                        dat[i-5]=binary(buf[i]-'0'-1);//将转换结果存放入dat中
					}
					else
						dat[i-5]=buf[i]-'0';//将转换结果存放入dat中
					printf("dat=%d\n",dat[i-5]);
				}
				for(i=0;i<13;i++)//接收数据打印
				{
					if((buf[i]-'0')>=10)
					{
						buf[i]=buf[i]-1;
						printf("buf=%x\n",buf[i]-'0');
					}
					else
						printf("buf=%x\n",buf[i]-'0');
				}
				id=dat[0]*16*16*16*16*16+dat[1]*16*16*16*16+dat[2]*16*16*16+dat[3]*16*16+dat[4]*16+dat[5];//计算id
				printf("id=%ld\n",id);
				h=dat[0]*16+dat[1];//计算韦根号
                printf("h=%d\n",h);
                l=dat[2]*16*16*16+dat[3]*16*16+dat[4]*16+dat[5];//计算韦根号
				printf("l=%d\n",l);
			}
		}
	}
	return 0;
}

二、GY39模块

1、模块引脚说明

实物图片(标号):


Pin1 VCC 电源+ (3v-5v)
Pin2 CT 串口 UART_TX / IIC_SCL
Pin3 DR 串口 UART_RX / IIC_SDA
Pin4 GND 电源地
Pin5 NC 保留,不要连接
Pin6 INT max44009 光强芯片中断 S1=0(接 GND 时启用)
Pin7 SDA 芯片数据总线 S1=0(接 GND 时启用)
Pin8 SCL 芯片时钟总线 S1=0(接 GND 时启用)
PinA S0 串口/MCU_IIC 模式选择
PinB S1 仅使用传感器芯片选择
注意:①, PinA(S0)硬件选择模块工作模式,Pin2(CT), Pin3(DR)为 GY-39 模块通讯接口,
S0=1(默认) 串口 UART 模式,Pin2 为 TX, Pin3 为 RX, TTL 电平
S0=0 (接 GND 时) MCU_IIC 模式, Pin2 为 SCL, Pin3 为 SDA,
②,PinB(S1)仅使用传感器芯片 BME280+MAX44009 模式,选择 MCU 是否参与数据处理工作,
S1=1(默认) MCU + 芯片模式,Pin7, Pin8,请不要有任何连接
S1=0 (接 GND 时) 仅芯片模式, Pin7 为芯片 SCL 总线, Pin8 为芯片 SDA 总线

2、通信协议

串口协议: 串口协议: 当 GY-39 模块硬件 PinA(S0)=1 时候使用
(1)、串口通信参数(默认波特率值 9600bps,可通过软件设定)
波特率:9600 bps 校验位:N 数据位:8 停止位:1
波特率:115200 bps 校验位:N 数据位:8 停止位:1
(2)、模块输出格式,每帧包含 8-13 个字节(十六进制):
①.Byte0: 0x5A 帧头标志
②.Byte1: 0x5A 帧头标志
③.Byte2: 0x15 本帧数据类型(参考含义说明)
④.Byte3: 0x04 数据量
⑤.Byte4: 0x00~0xFF 数据前高 8 位
⑤.Byte5: 0x00~0xFF 数据前低 8 位
⑥.Byte6: 0x00~0xFF 数据后高 8 位
⑦.Byte7: 0x00~0xFF 数据后低 8 位
⑧.Byte8: 0x00~0xFF 校验和(前面数据累加和,仅留低 8 位)
Byte2 代表的含义说明:
Byte2 0x15 0x45 0x55
含义: 光照强度 温度、气压、湿度、海拔 IIC 地址
(3)、数据计算方法
①光照强度计算方法(当 Byte2=0x15 时,数据:Byte4~Byte7) :
Lux=(前高8位<<24) | (前低8位<<16) | (后高8位<<8) | 后低8位 单位lux
例:一帧数据
<5A- 5A- 15 -04- 00 -00- FE- 40- 0B >
Lux=(0x00<<24)|(0x00<<16)|(0xFE<<8)|0x40
Lux=Lux/100 =650.88 (lux)
②温度、气压、湿度、海拔,计算方法(当 Byte2=0x45 时):
温度:Byte4~Byte5
T=(高 8 位<<8)|低 8 位
T=T/100 单位℃
气压:Byte6~Byte9
P=(前高 8 位<<24) | (前低 8 位<<16) | (后高 8 位<<8) | 后低 8 位
P=P/100 单位 pa
湿度:Byte10~Byte11
Hum=(高 8 位<<8)|低 8 位
Hum=Hum/100 百分制
海拔:Byte12~Byte13
H=(高 8 位<<8)|低 8 位 单位 m
例:一帧数据
< 5A -5A -45 -0A -0B -2D -00 -97 -C4 -3F -12- 77 -00- 9C- FA >
T=(0x0B<<8)|0x2D=2861
温度 T=2861/100=28.61 (℃)
P=(0x00<<24)|(0x97<<16)|(C4<<8)|3F=9946175
气压 P=9946175/100=99461.75 (pa)
Hum=(0x12<<8)| 77=4727
湿度 Hum=4727/100=47.27 (%)
海拔 H=(0x00<<8)|0x9c=156 (m)
③MCU_IIC 地址(当 Byte2=0x55 时):
IIC_ADD=Byte4
例:一帧数据
<5A-5A-55-01-B6-C0 >
IIC_ADD=0xB6 (8bit iic_add)
则 7bit iic_add 为 8bit iic_add 右移 1bit 得 0x5b
(4)、命令字节,由外部控制器发送至 GY-39 模块(十六进制)
1、所有串口指令格式,帧头:0xa5
指令格式:帧头+指令+校验和(8bit)
2、串口命令指令:
①,串口输出配置寄存器:
command Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0
输出命令 AUTO 0 0 0 0 0 BME MAX
AUTO(默认 1) 1:上电后按照上次的输出配置输出,0:上电后不自动输出
bit6-bit2 必需置零:00000
BME(默认 1)
1:连续输出温度、气压、湿度、海拔
0:不输出;
当 Auto 置 1,掉电保存
MAX(默认 1)
1:连续输出光照强度
0:不输出;
当 Auto 置 1,掉电保存
命令格式:0xA5+command+sum
例:bit7(Auto=1), bit0(MAX=1)
发送命令:0xA5+0x81+0x26,表示连续输出光照强度,掉电后保存该设置,重新上电后将
自动连续输出光照强度;
②,设置 IIC 地址指令:(该指令掉电保存修改后的 IIC 地址)
0xAA+XX+sum---------XX 表示 7bit IIC 地址,sum 等于 0xAA+XX 之和的低 8 位,例如
原厂 IIC 7bit 地址为 0x5B,则发送 0xAA+0x5B+05 到模块,7bit 地址左移一位,这样模块的
8bit IIC 地址为 0xB6
③,查询输出指令:
0xA5+0x51+0xF6 ---------------输出光照强度 (模块返回数据类型为 0x15)
0xA5+0x52+0xF7 ---------------输出温度、气压、湿度、海拔(模块返回数据类型为 0x45)
注:查询指令不掉电保存,如用查询输出,请注意在这之前是否配置了 command=0x00
④,波特率配置:
0xA5+0xAE+0x53 ---------------9600 (默认)
0xA5+0xAF+0x54 ---------------115200

3、相关代码

int   uart_init(const char * uart_name)

{

	/*设置串口

	  波特率:9600

	  数据位:8

	  校验位:不要

	  停止位:1

	  数据流控制:无

	  */

	

	int   uart1_fd= open(uart_name, O_RDWR);//打开串口1设备文件

	if (uart1_fd == -1)

	{

		perror("open error:");

		return -1;

	}



	struct termios myserial;

	//清空结构体

	memset(&myserial, 0, sizeof (myserial));

	//O_RDWR               

	myserial.c_cflag |= (CLOCAL | CREAD);

	//设置控制模式状态,本地连接,接受使能

	//设置 数据位

	myserial.c_cflag &= ~CSIZE;   //清空数据位

	myserial.c_cflag &= ~CRTSCTS; //无硬件流控制

	myserial.c_cflag |= CS8;      //数据位:8



	myserial.c_cflag &= ~CSTOPB;//   //1位停止位

	myserial.c_cflag &= ~PARENB;  //不要校验



	cfsetospeed(&myserial, B9600);  //设置波特率,B9600是定义的宏

	cfsetispeed(&myserial, B9600);



	/* 刷新输出队列,清除正接受的数据 */

	tcflush(uart1_fd, TCIFLUSH);



	/* 改变配置 */

	tcsetattr(uart1_fd, TCSANOW, &myserial);

	return   uart1_fd;

}

unsigned char GY39_cmd1[]={0xA5,0x81,0x26};//测光照强度命令

unsigned char GY39_cmd2[]={0xA5,0x52,0xF7};//测温度、湿度、大气、海拔命令



int GZ,WD,SD,QY,HB;

void get_GZ(int fd)

{

	int i=0,flag=0;

	unsigned char recvbuf[9]={0};

	write(fd,GY39_cmd1,3);

	while(1)

	{

		unsigned char buf ;

		read(fd,&buf,1);

		//printf("buf=%x\n",buf);

		if(buf == 0x5A)

		{

			flag = 1;

		}

		if(flag == 1)

		{

			//printf("buf=%x\n",buf);

			recvbuf[i++] = buf;

			if(i == 9)

			{

				break;

			}

		}

	}

	GZ = recvbuf[4]<<24 | recvbuf[5]<<16 | recvbuf[6]<<8 | recvbuf[7];

	GZ = GZ/100;

}



void get_other(int fd)

{

	int i=0,flag=0;

	unsigned char recvbuf[15]={0};

	write(fd,GY39_cmd2,3);

	while(1)

	{

		unsigned char buf ;

		read(fd,&buf,1);

		if(buf == 0x5A)

		{

			flag = 1;

		}

		if(flag == 1)

		{

			recvbuf[i++] = buf;

			if(i == 15)

			{

				break;

			}

		}

		

	}

	WD = recvbuf[4]<<8 | recvbuf[5];

	WD = WD/100;

	QY = recvbuf[6]<<24 | recvbuf[7]<<16 | recvbuf[8]<<8 | recvbuf[9];

	QY = QY/100;

	SD = recvbuf[10]<<8 | recvbuf[11];

	SD = SD/100;

	HB = recvbuf[12]<<8 | recvbuf[13];

}





int main()

{

	

	int uart1_fd = uart_init("/dev/ttySAC2");

   

    while(1)

    {

    	get_GZ(uart1_fd);

    	printf("GZ:%d\n",GZ);

    	sleep(1);

    	get_other(uart1_fd);

    	printf("WD:%d SD:%d QY:%d HB:%d\n",WD,SD,QY,HB);

    	sleep(1);

    }



	close(uart1_fd);

}

三、MQ2烟雾传感器

1、模块引脚说明

PIN1 VCC DC5V
PIN2 TXD 串口发送
PIN3 RXD 串口接收
PIN4 GND

2、通信协议

1        0x86   读传感器的浓度值
发送      0         1       2      3  4 5 6 7  8
             起始位 地址 命令 -- -- -- -- -- 校验值
              0xFF   0x01 0x86 0 0 0 0 0  0x79
EXP.      FF        01     86 00 00 00 00 00 79
返回      0          1       2                   3 4 5 6 7 8
             起始位 命令 传感器浓度值 -- -- -- -- 校验值
             0xFF 0x86 高字节 低字节 0 0 0 0 0xF5
EXP.     FF 86 00 85 00 00 00 00 F5

3、代码如下

int   uart_init(const char * uart_name)

{

	/*设置串口

	  波特率:9600

	  数据位:8

	  校验位:不要

	  停止位:1

	  数据流控制:无

	  */

	

	int   uart1_fd= open(uart_name, O_RDWR);//打开串口1设备文件

	if (uart1_fd == -1)

	{

		perror("open error:");

		return -1;

	}



	struct termios myserial;

	//清空结构体

	memset(&myserial, 0, sizeof (myserial));

	//O_RDWR               

	myserial.c_cflag |= (CLOCAL | CREAD);

	//设置控制模式状态,本地连接,接受使能

	//设置 数据位

	myserial.c_cflag &= ~CSIZE;   //清空数据位

	myserial.c_cflag &= ~CRTSCTS; //无硬件流控制

	myserial.c_cflag |= CS8;      //数据位:8



	myserial.c_cflag &= ~CSTOPB;//   //1位停止位

	myserial.c_cflag &= ~PARENB;  //不要校验



	cfsetospeed(&myserial, B9600);  //设置波特率,B9600是定义的宏

	cfsetispeed(&myserial, B9600);



	/* 刷新输出队列,清除正接受的数据 */

	tcflush(uart1_fd, TCIFLUSH);



	/* 改变配置 */

	tcsetattr(uart1_fd, TCSANOW, &myserial);

	return   uart1_fd;

}

unsigned char cmd[]={0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};



int value;

void get_value(int fd)

{

	int i=0,flag=0;

	unsigned char recvbuf[9]={0};

	write(fd,cmd,9);

	while(1)

	{

		unsigned char buf ;

		read(fd,&buf,1);

		

		if(buf == 0xFF)

		{

			flag = 1;

		}

		if(flag == 1)

		{

			printf("buf=%x\n",buf);

			recvbuf[i++] = buf;

			if(i == 9)

			{

				break;

			}

		}

	}

	value = recvbuf[2]<<8 | recvbuf[3];

}





int main()

{

	

	

	int uart1_fd = uart_init("/dev/ttySAC3");

	

    while(1)

    {

    	get_value(uart1_fd);

    	printf("MQ2 value:%d\n",value);

    	sleep(1);

    	

    }



	close(uart1_fd);

}

四、服务器TCP初始化

bool Widget::tcp_server_init()
{
    //实例化一个TCP服务器对象
    tcpServer = new QTcpServer(this);

    //服务器绑定IP地址和端口以及监听客户端的连接
    bool ok = tcpServer->listen(QHostAddress("192.168.31.111"),6666);
    if(!ok)
    {
        qDebug() << "tcpserver listen error:" << tcpServer->errorString();
        return false;
    }

    //当监听到客户端连接请求信号,就去处理该连接
    connect(tcpServer,&QTcpServer::newConnection,this,[=](){
        //从连接列表中获取下一个连接对象
        nextTcpSocket = tcpServer->nextPendingConnection();
        //实例化一个线程对象用来处理与客户端的通信
        tcp_thread= new Tcp_thread(nextTcpSocket,&map,this);

        //获取对端(客户端)的IP地址和端口号
        QString clientIp = nextTcpSocket->peerAddress().toString(); //获取IP地址
        quint16 port = nextTcpSocket->peerPort();   //获取端口号
        qDebug() << "client ip:" << clientIp << " client port:" << port;

        tcp_connect=true;
        ui->label_conn->setText("连接成功");

        //当客户端断开连接的时候,也要进行相应的处理
        connect(nextTcpSocket,&QTcpSocket::disconnected,this,[=](){
            //客户端断开连接
            qDebug() << "client disconnected!";
            //关闭套接字
            nextTcpSocket->close();
            //延时释放套接字资源,防止其他地方有用到资源,还没用完,等他们用完了再释放
            nextTcpSocket->deleteLater();
            tcp_connect=false;
            ui->label_conn->clear();
        });

        //当套接字的连接状态发生变化的时候,会发送信号stateChanged
        connect(nextTcpSocket,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,\
                SLOT(m_on_state_changed(QAbstractSocket::SocketState)));

        //tcp线程消息
        connect(tcp_thread,&Tcp_thread::Message,this,[=](QString text){
            QString time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//获取当前时间
            ui->textEdit_call->setTextColor(Qt::red);//设置颜色
            ui->textEdit_call->append("["+time+"]"+text);//追加到收发区
            call_falge=true;
        });

        tcp_thread->start();
        connect(tcp_thread,&Tcp_thread::Date,this,[=](QString text){
            qDebug()<<"text:"<<text;
            int i=0;
            QStringList list = text.split(",");
            QStringList::iterator it;
            for ( it= list.begin(); it != list.end(); ++it) {
                QString s=*it;
                date[i]=*it;
                i++;
            }

            ui->lineEdit_fumes->setText(date[4]);
            ui->lineEdit_gz->setText(date[0]);
            ui->lineEdit_humidity->setText(date[3]);
            ui->lineEdit_qy->setText(date[2]);
            ui->lineEdit_temp->setText(date[1]);
        });
    });

    return true;
}

void Widget::m_on_state_changed(QAbstractSocket::SocketState state)
{
    //    QAbstractSocket::UnconnectedState   表示未连接状态,即还没有建立连接
    //    QAbstractSocket::HostLookupState    正在进行主机名解析的状态,即正在将主机名转换成IP地址
    //    QAbstractSocket::ConnectingState    正在尝试连接的状态
    //    QAbstractSocket::ConnectedState     已经连接的状态
    //    QAbstractSocket::BoundState         已绑定到一个本地地址的状态,等待连接请求
    //    QAbstractSocket::ClosingState       正在关闭连接的状态
    //    QAbstractSocket::ListeningState     正在监听连接请求的状态
    switch (state)
    {
    case QAbstractSocket::UnconnectedState:
        ui->label_conn->setText("未连接状态");
        qDebug() << "no connect";
        break;
    case QAbstractSocket::HostLookupState:
        ui->label_conn->setText("正在进行主机名解析的状态");
        qDebug() << "The status of host name resolution in progress";
        break;
    case QAbstractSocket::ConnectingState:
        ui->label_conn->setText("正在尝试连接的状态");
        qDebug() << "The status of the attempted connection";
        break;
    case QAbstractSocket::ConnectedState:
        ui->label_conn->setText("已经连接的状态");
        qDebug() << "The status of the connection";
        break;
    case QAbstractSocket::BoundState:
        ui->label_conn->setText("已绑定到一个本地地址的状态,等待连接请求");
        qDebug() << "A state that has been bound to a local address, waiting for a connection request";
        break;
    case QAbstractSocket::ClosingState:
        ui->label_conn->setText("正在关闭连接的状态");
        qDebug() << "The status of closing the connection";
        break;
    case QAbstractSocket::ListeningState:
        ui->label_conn->setText("正在监听连接请求的状态");
        qDebug() << "Listening for the status of connection requests";
        break;
    default:
        ui->label_conn->setText("未知状态");
        qDebug() << "Unknown status";
        break;
    }
}

五、客户端TCP欻化

bool Widget::tcp_client_init()
{
    //实例化一个客户端套接字
    tcpClient = new QTcpSocket{this};
//    //给客户端绑定IP地址和端口号
//    bool ok = tcpClient->bind(QHostAddress("192.168.137.145"),8888);
//    if(!ok)
//    {
//        qDebug() << "client bind error:" << tcpClient->errorString();
//        return false;
//    }
    //连接服务器
    tcpClient->connectToHost(QHostAddress("192.168.1.106"),6666);
    //当服务器有数据发过来的时候,会发送信号 readyRead,所以要将这个信号连接到槽函数
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(m_on_ready_read()));
    //当套接字的连接状态发生变化的时候,会发送信号stateChanged
    connect(tcpClient,SIGNAL(stateChanged(QAbstractSocket::SocketState)),this,SLOT(m_on_state_changed(QAbstractSocket::SocketState)));
    //当断开连接时,会发送信号disconnected
    connect(tcpClient,SIGNAL(disconnected()),this,SLOT(m_on_disconnected()));
    if(tcpClient->state() != QAbstractSocket::UnconnectedState)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void Widget::m_on_ready_read()
{
    //读取服务器发过来的数据
    QString text = tcpClient->readAll();
    qDebug() << "receive:" << text;
    int i=0;
    //解析数据
    if(text.left(5) == "data:")
    {
        QStringList list = text.mid(5).split(",");
        QStringList::iterator it;
        for ( it= list.begin(); it != list.end(); ++it) {
            QString s=*it;
            data[i]=*it;
            i++;
        }
    }
    else if(text.left(4) == "ack:")
    {
        QString s=QString{"%1"}.arg(text.mid(4));
        QMessageBox::warning(this,"warn",s);
    }
}

void Widget::m_on_state_changed(QAbstractSocket::SocketState state)
{
//    QAbstractSocket::UnconnectedState   表示未连接状态,即还没有建立连接
//    QAbstractSocket::HostLookupState    正在进行主机名解析的状态,即正在将主机名转换成IP地址
//    QAbstractSocket::ConnectingState    正在尝试连接的状态
//    QAbstractSocket::ConnectedState     已经连接的状态
//    QAbstractSocket::BoundState         已绑定到一个本地地址的状态,等待连接请求
//    QAbstractSocket::ClosingState       正在关闭连接的状态
//    QAbstractSocket::ListeningState     正在监听连接请求的状态
    switch (state)
    {
    case QAbstractSocket::UnconnectedState:
        qDebug() << "未连接状态";
        break;
    case QAbstractSocket::HostLookupState:
        qDebug() << "正在进行主机名解析的状态";
        break;
    case QAbstractSocket::ConnectingState:
        qDebug() << "正在尝试连接的状态";
        break;
    case QAbstractSocket::ConnectedState:
        qDebug() << "已经连接的状态";
        break;
    case QAbstractSocket::BoundState:
        qDebug() << "已绑定到一个本地地址的状态,等待连接请求";
        break;
    case QAbstractSocket::ClosingState:
        qDebug() << "正在关闭连接的状态";
        break;
    case QAbstractSocket::ListeningState:
        qDebug() << "正在监听连接请求的状态";
        break;
    default:
        qDebug() << "未知状态";
        break;
    }
}

总结

经过这个小项目我获得了很多收获,对linux操作系统和QT有了更加深刻的理解。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值