4G模块使用TCP实现MQTT协议

最近做项目使用模块的MQTT功能,但是由于MQTT没有透传模式,发送接收使用AT指令太频繁的话容易出错。

今天在技术群里偶然听说了可以使用TCP模式,自己再在TCP的基础上封装一层MQTT数据协议,想了一下确实可行。

在网上找了一下,发现一段代码如下:

int strlen(char *str)
{
    int len = 0;
    while (*str != '\0') {
        len++;
        str++;
    }
    return len;
}
 
// **********************************
// *                                *
// * 根据主机地址和端口号连接服务器 *
// *                                *
// **********************************
 
 
void tcp_connect(char *host,int port)
{
   uart_send_str("AT\r\n");
   uart_send_str("AT+CPIN? \r\n");
   seelp(500);
   uart_send_str("AT+CREG? \r\n");
   seelp(500);
   uart_send_str("AT+CGATT? \r\n");
   seelp(500);
   uart_send_str("AT+CSTT=\"CMNET\" \r\n");
   seelp(500);
   uart_send_str("AT+CIICR \r\n");
   seelp(1500);
   uart_send_str("AT+CIFSR \r\n");
   seelp(1000);
   uart_send_str("AT+CIPSTART=\"TCP\"\,\"23.106.139.167\"\,\"1883\" \r\n"); //连接TCP Server  8081 1883
}
 
 
// *************************
// *                       *
// *  构建MQTT连接包       *
// *                       *
// *************************
 
int baseIndex;
int mqtt_connect_message(unsigned char *mqtt_message,char *client_id,char *username,char *password)
{ 
    char i = 0;  
    char client_id_length = strlen(client_id);  
    int username_length = strlen(username);  
    int password_length = strlen(password);  
    int packetLen = 12 + 2 + client_id_length + 2 + username_length + 2 + password_length;  
      
    mqtt_message[0] = 16;                      // MQTT Message Type CONNECT  
    mqtt_message[1] = packetLen%256;  
    baseIndex = 2;  
    if( packetLen >127 ){//  
        mqtt_message[2] = 1;//packetLen/127;  
        baseIndex = 3;  
    }  
      
      
    mqtt_message[baseIndex] = 0;                       // Protocol Name Length MSB  
    mqtt_message[baseIndex+1] = 6;                       // Protocol Name Length LSB  
    mqtt_message[baseIndex+2] = 77;                      // ASCII Code for M  
    mqtt_message[baseIndex+3] = 81;                      // ASCII Code for Q  
    mqtt_message[baseIndex+4] = 73;                      // ASCII Code for I  
    mqtt_message[baseIndex+5] = 115;                     // ASCII Code for s  
    mqtt_message[baseIndex+6] = 100;                     // ASCII Code for d  
    mqtt_message[baseIndex+7] = 112;                     // ASCII Code for p  
    mqtt_message[baseIndex+8] = 3;                      // MQTT Protocol version = 3  
    mqtt_message[baseIndex+9] = 194;                   // conn flags  
    mqtt_message[baseIndex+10] = 0;                      // Keep-alive Time Length MSB  
    mqtt_message[baseIndex+11] = 60;                     // Keep-alive Time Length LSB  
      
    mqtt_message[baseIndex+12] = 0;                      // Client ID length MSB  
    mqtt_message[baseIndex+13] = client_id_length;       // Client ID length LSB  
      
    baseIndex += 14;  
    // Client ID  
    for(i = 0; i < client_id_length; i++){  
        mqtt_message[baseIndex + i] = client_id[i];  
    }  
      
    baseIndex = baseIndex+client_id_length;  
      
    //username  
    mqtt_message[baseIndex] = 0;                      //username length MSB  
    mqtt_message[baseIndex+1] = username_length;       //username length LSB  
    baseIndex = baseIndex+2;  
    for(i = 0; i < username_length ; i++){  
        mqtt_message[baseIndex + i] = username[i];  
    }  
      
    baseIndex = baseIndex + username_length;  
      
    //password  
    mqtt_message[baseIndex] = 0;                      //password length MSB  
    mqtt_message[baseIndex+1] = password_length;       //password length LSB  
    baseIndex = baseIndex + 2;  
    for(i = 0; i < password_length ; i++){  
        mqtt_message[baseIndex + i] = password[i];  
    }  
      
    baseIndex += password_length;  
  
    return baseIndex;  
}
 
 
int mqtt_publish_message(unsigned char *mqtt_message, char * topic, char * message) {  
      
    //mqtt_message = 0;  
      
    unsigned char i = 0;  
    unsigned char topic_length = strlen(topic);  
    unsigned char message_length = strlen(message);  
      
    mqtt_message[0] = 48;                                  // MQTT Message Type CONNECT  
    mqtt_message[1] = 2 + topic_length + message_length;   // Remaining length  
    mqtt_message[2] = 0;                                   // MQTT Message Type CONNECT  
    mqtt_message[3] = topic_length;                        // MQTT Message Type CONNECT  
      
    // Topic  
    for(i = 0; i < topic_length; i++){  
        mqtt_message[4 + i] = topic[i];  
    }  
      
    // Message  
    for(i = 0; i < message_length; i++){  
        mqtt_message[4 + topic_length + i] = message[i];  
    }  
      
    return 4 + topic_length + message_length;  
}  
 
 
int subindex = 0;
int mqtt_subscribe_message(unsigned char *mqtt_message,unsigned char *topic)  
{  
    unsigned char topic_len = strlen(topic);  
    mqtt_message[0] = 130;  
    mqtt_message[1] = topic_len+5;  
    mqtt_message[2] = 0;  
    mqtt_message[3] = 1;  
    mqtt_message[4] = 0;  
    mqtt_message[5] = topic_len;  
 
    for (subindex=0; subindex<topic_len; subindex++) {  
        mqtt_message[6+subindex] = topic[subindex];  
    }  
    mqtt_message[topic_len+6+1] = 0;  
    return topic_len+7;  
}

再根据MQTT协议:https://mcxiaoke.gitbooks.io/mqtt-cn/content/ 

对比发现应该是可行的,近期没有项目,就不测试了,下次测试会在此处更新测试结果。(已测试,代码好用,但是需要自己增加和修改,上面的代码只是起到封装数据的作用,另外还有其他相关的MQTT服务,后续我会自己写,写完会更新到这里)

代码取自博客:https://blog.csdn.net/pz0605/article/details/60964587

经过实际项目验证,上面的代码只能发送不超过128字节的数据,如果需要发送更多的数据,需要自己修改协议层代表数据长度的字节。这里贴一下我改过的,可以发送16000+字节。

int baseIndex;
int mqtt_connect_message(unsigned char *mqtt_message,char *client_id,char *username,char *password)
{ 
    char i = 0;  
    char client_id_length = sel_strlen(client_id);  
    int username_length = sel_strlen(username);  
    int password_length = sel_strlen(password);  
    int packetLen = 12 + 2 + client_id_length + 2 + username_length + 2 + password_length;  
      
    mqtt_message[0] = 16;                      // MQTT Message Type CONNECT  
    mqtt_message[1] = packetLen%256;  
    baseIndex = 2;  
    if( packetLen >127 ){//  
        mqtt_message[2] = 1;//packetLen/127;  
        baseIndex = 3;  
    }  
      
      
    mqtt_message[baseIndex] = 0;                       // Protocol Name Length MSB  
    mqtt_message[baseIndex+1] = 6;                       // Protocol Name Length LSB  
    mqtt_message[baseIndex+2] = 77;                      // ASCII Code for M  
    mqtt_message[baseIndex+3] = 81;                      // ASCII Code for Q  
    mqtt_message[baseIndex+4] = 73;                      // ASCII Code for I  
    mqtt_message[baseIndex+5] = 115;                     // ASCII Code for s  
    mqtt_message[baseIndex+6] = 100;                     // ASCII Code for d  
    mqtt_message[baseIndex+7] = 112;                     // ASCII Code for p  
    mqtt_message[baseIndex+8] = 3;                      // MQTT Protocol version = 3  
    mqtt_message[baseIndex+9] = 194;                   // conn flags  
    mqtt_message[baseIndex+10] = 0;                      // Keep-alive Time Length MSB  
    mqtt_message[baseIndex+11] = 60;                     // Keep-alive Time Length LSB  
      
    mqtt_message[baseIndex+12] = 0;                      // Client ID length MSB  
    mqtt_message[baseIndex+13] = client_id_length;       // Client ID length LSB  
      
    baseIndex += 14;  
    // Client ID  
    for(i = 0; i < client_id_length; i++){  
        mqtt_message[baseIndex + i] = client_id[i];  
    }  
      
    baseIndex = baseIndex+client_id_length;  
      
    //username  
    mqtt_message[baseIndex] = 0;                      //username length MSB  
    mqtt_message[baseIndex+1] = username_length;       //username length LSB  
    baseIndex = baseIndex+2;  
    for(i = 0; i < username_length ; i++){  
        mqtt_message[baseIndex + i] = username[i];  
    }  
      
    baseIndex = baseIndex + username_length;  
      
    //password  
    mqtt_message[baseIndex] = 0;                      //password length MSB  
    mqtt_message[baseIndex+1] = password_length;       //password length LSB  
    baseIndex = baseIndex + 2;  
    for(i = 0; i < password_length ; i++){  
        mqtt_message[baseIndex + i] = password[i];  
    }  
      
    baseIndex += password_length;  
  
		usart2_SendHex(mqtt_message,baseIndex);
    return baseIndex;  
}
 
 
int mqtt_publish_message( char *mqtt_message, char * topic, char * message,int message_len) {  
      
    //mqtt_message = 0;  
    // printf("111111\r\n");  
    int i = 0;  
		unsigned char len1,len2;
    int topic_length = sel_strlen(topic);  
    int message_length = message_len;
		printf("message_length = %d\r\n",message_length);
   // printf("222222\r\n");
	
		len1 = (2+topic_length +message_length)/128;
		len2 = ((2+topic_length +message_length)%128) + 128;
		if(len1>0)
		{
			mqtt_message[0] = 48;                                  // MQTT Message Type CONNECT  
			mqtt_message[1] = len2;   // Remaining length  
			mqtt_message[2] = len1;                                   // MQTT Message Type CONNECT  
			mqtt_message[3] = 0;
			mqtt_message[4] = topic_length;                        // MQTT Message Type CONNECT  
				
			// Topic  
			for(i = 0; i < topic_length; i++){  
					mqtt_message[5 + i] = topic[i];  
			}  
				
			// Message  
			for(i = 0; i < message_length; i++){  
					mqtt_message[5 + topic_length + i] = message[i];  
			}
			printf("mqtt_message:");
			for(i=0;i<(5 + topic_length + message_length);i++)
			{
				printf("%c",mqtt_message[i]);
			}
			printf("\r\n");
		//	printf("333333\r\n");
			usart2_SendHex(mqtt_message,5 + topic_length + message_length);  
		}
		else
		{
			mqtt_message[0] = 48;                                  // MQTT Message Type CONNECT  
			mqtt_message[1] = 2 + topic_length + message_length;   // Remaining length  
			mqtt_message[2] = 0;                                   // MQTT Message Type CONNECT  
			mqtt_message[3] = topic_length;                        // MQTT Message Type CONNECT  
      
    // Topic  
			for(i = 0; i < topic_length; i++){  
					mqtt_message[4 + i] = topic[i];  
			}  
				
			// Message  
			for(i = 0; i < message_length; i++){  
					mqtt_message[4 + topic_length + i] = message[i];  
			}  
			printf("mqtt_message:");
			for(i=0;i<(4 + topic_length + message_length);i++)
			{
				printf("%c",mqtt_message[i]);
			}
			printf("\r\n");
		//	printf("333333\r\n");
			usart2_SendHex(mqtt_message,4 + topic_length + message_length);  
		
			
		}
	//	printf("444444\r\n");
    return 0;  
}  
 
 
int subindex = 0;
int mqtt_subscribe_message(unsigned char *mqtt_message,unsigned char *topic)  
{  
    unsigned char topic_len = sel_strlen(topic);  
    mqtt_message[0] = 130;  
    mqtt_message[1] = topic_len+5;  
    mqtt_message[2] = 0;  
    mqtt_message[3] = 1;  
    mqtt_message[4] = 0;  
    mqtt_message[5] = topic_len;  
 
    for (subindex=0; subindex<topic_len; subindex++) {  
        mqtt_message[6+subindex] = topic[subindex];  
    }  
    mqtt_message[topic_len+6+1] = 0; 
		usart2_SendHex(mqtt_message,topic_len+7);
    return 0;  
}

 

 

 

 

 

还有一种方法就是使用C库,将模块设置入网,通过C库来建立socket连接MQTT服务器并发布订阅主题数据。

提供一下网上的C库:https://github.com/eclipse/paho.mqtt.embedded-c

 

  • 6
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值