嵌入式linux閘道器程式
實現的功能:
使用linuxC語言通過串列埠程式設計和Socket程式設計,以及解析從串列埠收到的資料,並且把資料封裝成http格式通過post方式可以實現遠端傳送資料到伺服器,並且能夠接收伺服器傳送過來的命令。
關於HTTP請求報文格式
關鍵程式碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <string.h>
#include <netdb.h>
#include "cssl.h"
//全域性變數這邊設定裝置地址,IP,埠號,以及sockfd
char* dev_path;
char* ip = NULL;
int port;
int sockfd;
//把資料封裝成http格式,並且通過post方式傳送溫溼度資料
void sendDatawenshidu(uint8_t *buf,int length)
{
printf("buf:%s\n",buf);
//介面
char page[] = "addWendu";
char content[4096];
char content_page[50];
char content_host[50];
char content_len[50];
//1請求行
sprintf(content_page,"POST /%s HTTP/1.1\r\n",page);
/*2.請求頭部
/Host:請求的主機名,允許多個域名同處一個IP地址,即虛擬主機。
*/
sprintf(content_host,"HOST: %s:%d\r\n",ip,port);
/*4.請求資料
/請求資料不在GET方法中使用,而是在POST方法中使用。
/POST方法適用於需要客戶填寫表單的場合。與請求資料相
/關的最常使用的請求頭是Content-Type和Content-Length。
*/
char content_type[] = "Content-Type: application/x-www-form-urlencoded\r\n";
sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(buf));
sprintf(content,"%s%s%s%s%s",content_page,content_host,content_type,content_len,buf);
send(sockfd,content,strlen(content),0);
}
//把資料封裝成http格式,並且通過post方式傳送光照值資料
void sendDataguangzhao(uint8_t *buf,int length)
{
printf("buf:%s\n",buf);
char page[] = "Guangzhao";
char content[4096];
char content_page[50];
char content_len[50];
char content_host[50];
sprintf(content_page,"POST /%s HTTP/1.1\r\n",page);
sprintf(content_host,"HOST: %s:%d\r\n",ip,port);
char content_type[] = "Content-Type: application/x-www-form-urlencoded\r\n";
sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(buf));
sprintf(content,"%s%s%s%s%s",content_page,content_host,content_type,content_len,buf);
send(sockfd,content,strlen(content),0);
}
//把資料封裝成http格式,並且通過post方式傳送可燃氣體值資料
void sendDataGas(uint8_t *buf,int length)
{
printf("buf:%s\n",buf);
char page[] = "Gas";
char content[4096];
char content_page[50];
char content_host[50];
char content_len[50];
sprintf(content_page,"POST /%s HTTP/1.1\r\n",page);
sprintf(content_host,"HOST: %s:%d\r\n",ip,port);
char content_type[] = "Content-Type: application/x-www-form-urlencoded\r\n";
sprintf(content_len,"Content-Length: %d\r\n\r\n",strlen(buf));
sprintf(content,"%s%s%s%s%s",content_page,content_host,content_type,content_len,buf);
send(sockfd,content,strlen(content),0);
}
//回撥函式,列印串列埠收到的資料的資訊,在這個方法中對串列埠收到的資料進行解析,並且呼叫通過socket傳送資料給伺服器
static void callback(int id, uint8_t *buf,int length)
{
int i;
char dtype[2],data[50];
printf("the date from serial:%s\n", buf);
printf("\nread serial success: length = %d\n", length);
sprintf(dtype,"%d",buf[2]);
switch(dtype[0]){
case '1':
sprintf(data,"wendu=%d&shidu=%d",buf[5],buf[6]);
puts(data);
sendDatawenshidu(data,strlen(data));
break;
case '2':
sprintf(data,"gz=%d",buf[5]);
puts(data);
sendDataguangzhao(data,strlen(data));
break;
case '3':
sprintf(data,"gs=%d",buf[5]);
puts(data);
sendDataGas(data,strlen(data));
break;
default:
puts("the date is error");
break;
}
}
int main( int argc, char **argv ){
dev_path = (char*)argv[1];
ip = (char*)argv[2];
port = atoi(argv[3]);
char buffer[64];
if( argc < 4 ){
fprintf( stderr,"usage: %s dev_path,ip and post\n",argv[0] );
exit(1);
}
//serial part串列埠部分
cssl_t *ser;
cssl_start();
ser=cssl_open(dev_path,callback,0,38400,8,0,1);
if (!ser){
printf("%s\n",cssl_geterrormsg());
}
printf("Serial connection successful, DEV = %s\n", dev_path);
//create socket
//建立socket 建立一個sock連線
sockfd = socket( AF_INET,SOCK_STREAM,0 );
if ( sockfd < 0 )
{
fprintf( stderr, "socket:%s\n", strerror(errno));
exit(1);
}
else{
printf("success to connect the service\n");
}
struct sockaddr_in sockaddr;
//設定連線資訊結構
memset( &sockaddr,0,sizeof(sockaddr) );
sockaddr.sin_family = AF_INET;
sockaddr.sin_port = htons ( atoi (port) );
inet_pton(AF_INET,ip,&sockaddr.sin_addr.s_addr);
socklen_t len = sizeof(sockaddr);
//連線到遠端伺服器
if( connect(sockfd,(struct sockaddr*)&sockaddr,len) <0 ){
fprintf(stderr, "connect: %s\n", strerror(errno) );
exit(1);
}
//receive from service :
memset( buffer,0,sizeof(buffer) );
ssize_t n;
while(1){
if( (n = read(sockfd,buffer,1024)) > 0) {
printf("receive from service :");
puts(buffer);
printf("\n");
cssl_putstring(ser,buffer);
printf("the serial receive the commend from service !\n");
}
}
for(;;);
close(sockfd);
return 0;
}
具體詳細的專案程式碼可以到筆者github倉庫下載:https://github.com/Wlain/-linuxC-Socket-http-post-.git
相關文章
- Janusec應用安全閘道器(WAF閘道器)
- Linux下檢視閘道器方法:Linux
- Linux 修改IP地址和閘道器Linux
- 閘道器GatewayGateway
- 什麼是閘道器?閘道器的作用是什麼,閘道器的作用詳解
- linux閘道器下的TC控速Linux
- linux 下修改IP和閘道器方法 。Linux
- Linux下的閘道器設定(轉)Linux
- API閘道器,企業級閘道器可擴充套件API套件
- Linux系統預設閘道器怎麼更改?Linux系統預設閘道器的更改方法教程Linux
- API 閘道器 KongAPI
- 微服務閘道器微服務
- Zuul路由閘道器Zuul路由
- 《springcloud 二》微服務動態閘道器,閘道器叢集SpringGCCloud微服務
- 小米智慧閘道器玩法介紹 小米閘道器怎麼用?
- Linux 中如何查詢預設閘道器Linux
- 微服務閘道器- Nginx微服務Nginx
- Gateway(閘道器)的概述Gateway
- 基於Linux和IPSec的VPN閘道器Linux
- 開放API閘道器實踐(一) ——設計一個API閘道器API
- 預設閘道器怎麼設定,預設閘道器是什麼
- 服務閘道器過濾器過濾器
- 高效能API閘道器(1)、微服務API閘道器架構設計API微服務架構
- Linux虛擬機器遷移後ping不通閘道器Linux虛擬機
- 微服務中的閘道器微服務
- Docker 安裝 Kong 閘道器Docker
- 並行閘道器 Parallel Gateway並行ParallelGateway
- Tyk閘道器Docker安裝Docker
- SpringCloud(四)GateWay閘道器SpringGCCloudGateway
- SpringCloud(五)GateWay閘道器SpringGCCloudGateway
- Spring Cloud Zuul 閘道器SpringCloudZuul
- 物聯網的閘道器
- API 閘道器策略二三事API
- ORACLE透明閘道器的配置Oracle
- transparent gateway 透明閘道器配置Gateway
- linux下修改ip地址,預設閘道器以及DNSLinuxDNS
- 億級流量架構之閘道器設計思路、常見閘道器對比架構
- 判斷閘道器合法性程式碼例項