智能家居 (7) ——网络服务器线程控制
目錄
- 網(wǎng)絡(luò)線程控制代碼
- inputCommand.h
- mainPro.c
- socketControl.c
- 代碼測(cè)試
- 往期文章
網(wǎng)絡(luò)線程控制代碼
inputCommand.h
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <wiringPi.h> #include <wiringSerial.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>struct Command {char commandName[128]; //“控制方式”名char deviceFilesName[128]; //存放初始化所需文件的路徑char command[32]; //存放指令int fd; //存放文件描述符(串口/網(wǎng)絡(luò))int (*Init)(struct Command *file); //“初始化”函數(shù)指針int s_fd; //存放服務(wù)器套接字描述符char ipAdress[32]; //存放 IP地址char port[12]; //存放端口號(hào)int (*getCommand)(struct Command *cmd); //“獲取指令”函數(shù)指針struct Command *next; };struct Command *addSocketControlToCommandLink(struct Command *phead); //“網(wǎng)絡(luò)控制”加入指令鏈表函數(shù)聲明mainPro.c
#include <stdio.h> #include <string.h> #include "inputCommand.h" #include <pthread.h> #include <unistd.h>struct Command *findCommandByName(char *name,struct Command *phead); //尋找鏈節(jié)函數(shù)聲明 void *socketControlThread(void *data); //“網(wǎng)絡(luò)控制”線程函數(shù)聲明 void *socketReadThread(void *data); //“讀取端口”線程函數(shù)聲明struct Command *cmdhead = NULL; //創(chuàng)建“指令”鏈表全局變量 struct Command *socketHandler = NULL; //創(chuàng)建“鏈節(jié)處理”全局變量int main() {cmdhead = addSocketControlToCommandLink(cmdhead); //“網(wǎng)絡(luò)控制”對(duì)象加入鏈表pthread_t socketControl_thread;pthread_create(&socketControl_thread,NULL,socketControlThread,NULL); //創(chuàng)建“網(wǎng)絡(luò)控制”線程pthread_join(socketControl_thread, NULL); //主函數(shù)等待“網(wǎng)絡(luò)控制”線程退出return 0; }void *socketControlThread(void *data) //“網(wǎng)絡(luò)控制”線程 {int c_fd; //文件描述符struct sockaddr_in c_addr;memset(&c_addr,0,sizeof(struct sockaddr_in));socklen_t clen = sizeof(struct sockaddr_in);pthread_t socketRead_thread; //存放線程 IDsocketHandler = findCommandByName("socketControl",cmdhead); //尋找并返回“網(wǎng)絡(luò)控制”所處鏈節(jié)if(socketHandler == NULL){ //若找不到printf("find socketHandler error\n");pthread_exit(NULL);}if(socketHandler->Init(socketHandler) < 0){ //執(zhí)行“網(wǎng)絡(luò)控制”功能初始化函數(shù)printf("socketControl init error\n");pthread_exit(NULL);}while(1){//不斷等待連接 只要有連接進(jìn)來(lái),就創(chuàng)建線程去對(duì)接c_fd = accept(socketHandler->s_fd,(struct sockaddr*)&c_addr,&clen); //接收連接請(qǐng)求socketHandler->fd = c_fd; //發(fā)送文件描述符pthread_create(&socketRead_thread,NULL,socketReadThread,NULL); //創(chuàng)建“讀取端口”線程 連接一個(gè)客戶端就去對(duì)接 可接納10個(gè)客戶端} } //創(chuàng)建新線程:用于讀取TCP端口指令 //只要有連接,就創(chuàng)建線程去對(duì)接。線程共用內(nèi)存資源,同一時(shí)刻,所有設(shè)備只有一種狀態(tài)。也可PV操作 //所有線程 只操控一個(gè)結(jié)構(gòu)體 再新來(lái)一個(gè)線程(新手機(jī)客戶端接入) 前一個(gè)客戶端失效 因?yàn)閏_fd被改了。fork()可實(shí)現(xiàn)多個(gè)客戶端同時(shí)控制 //不過(guò)好像寄存器和內(nèi)存不是完全同步的 可能緩存沒(méi)改?還可以多個(gè)客戶端同時(shí)控制? //如果直接把socketReadThread()拿過(guò)來(lái)循環(huán)的話,則同時(shí)刻不能接受新的客戶端接入了,因?yàn)檠h(huán)卡在了socketReadThread()函數(shù)里面了//“讀取端口”線程 void *socketReadThread(void *data) //實(shí)際沒(méi)傳參 {int nread;memset(socketHandler->command,'\0',sizeof(socketHandler->command)); //每次讀取前,清空 “command(存放指令)”nread = read(socketHandler->fd,socketHandler->command,sizeof(socketHandler->command)); //讀取客戶端并存放到 “command”if(nread == 0){printf("No command received\n");}else{printf("Get command:%s\n",socketHandler->command); //讀取成功,打印數(shù)據(jù)} }struct Command *findCommandByName(char *name,struct Command *phead) //通過(guò)“名字”尋找鏈節(jié)函數(shù) {struct Command *tmp = phead;if(phead == NULL){return NULL;}while(tmp != NULL){if(strcmp(name,tmp->commandName) == 0){return tmp;}tmp = tmp->next;}return NULL; }socketControl.c
#include "inputCommand.h" #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <string.h> #include <unistd.h>int socketControlInit(struct Command *file); //“網(wǎng)絡(luò)控制”功能初始化函數(shù)聲明 struct Command *addSocketControlToLink(struct Command *phead); //“網(wǎng)絡(luò)控制”(對(duì)象)加入指令鏈表函數(shù)聲明struct Command socketControl = { //定義“網(wǎng)絡(luò)控制”對(duì)象.commandName = "socketControl", //名字.command = {'\0'}, //初始化儲(chǔ)存“指令”的空間.Init = socketControlInit, //指定“網(wǎng)絡(luò)控制”功能初始化函數(shù).ipAdress = "192.168.0.19", //樹(shù)莓派 IP地址.port = "8088", //打開(kāi)的端口號(hào) };int socketControlInit(struct Command *file) {int s_fd; //套接字描述符struct sockaddr_in s_addr;memset(&s_addr,0,sizeof(struct sockaddr_in));s_fd = socket(AF_INET,SOCK_STREAM,0); //創(chuàng)建套接字if(s_fd == -1){ //若創(chuàng)建套接字失敗perror("socketControl error");exit(-1);}s_addr.sin_family = AF_INET;s_addr.sin_port = htons(atoi(file->port));inet_aton(file->ipAdress,&s_addr.sin_addr);if(bind(s_fd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in)) == -1){ //套接字與端口號(hào)綁定perror("bind error");exit(-1);}if(listen(s_fd,10) == -1){ //打開(kāi)監(jiān)聽(tīng)perror("listen error");exit(-1);}file->s_fd = s_fd; //發(fā)送套接字描述符 }struct Command *addSocketControlToCommandLink(struct Command *phead) //“網(wǎng)絡(luò)控制”(對(duì)象)加入指令鏈表函數(shù) {if(phead == NULL){return &socketControl;}else{socketControl.next = phead;phead = &socketControl;return phead;} }代碼測(cè)試
手機(jī)下載網(wǎng)絡(luò)調(diào)試助手,和樹(shù)莓派連入同一個(gè)WIFI,輸入樹(shù)莓派IP地址以及端口號(hào),發(fā)送消息:Today is 520,樹(shù)莓派接收消息成功。
往期文章
智能家居 (1) ——智能家居整體功能框架
智能家居 (2) ——設(shè)計(jì)模式的引入
智能家居 (3) ——工廠模式繼電器控制燈
智能家居 (4) ——工廠模式火焰報(bào)警
智能家居 (5) —— LD3320語(yǔ)音模塊二次開(kāi)發(fā)
智能家居 (6) ——語(yǔ)音識(shí)別線程控制
智能家居 (7) ——網(wǎng)絡(luò)服務(wù)器線程控制
智能家居 (8) ——智能家居項(xiàng)目整合(網(wǎng)絡(luò)控制線程、語(yǔ)音控制線程,火災(zāi)報(bào)警線程)
網(wǎng)絡(luò)編程知識(shí)預(yù)備(1) ——了解OSI網(wǎng)絡(luò)模型
網(wǎng)絡(luò)編程知識(shí)預(yù)備(2) ——淺顯易懂的三次握手與四次揮手
網(wǎng)絡(luò)編程知識(shí)預(yù)備(3) ——SOCKET、TCP、HTTP之間的區(qū)別與聯(lián)系
網(wǎng)絡(luò)編程知識(shí)預(yù)備(4) ——了解HTTP協(xié)議與HTTPS協(xié)議
網(wǎng)絡(luò)編程知識(shí)預(yù)備(5) ——libcurl庫(kù)簡(jiǎn)介及其編程訪問(wèn)百度首頁(yè)
智能家居 (9) ——人臉識(shí)別攝像頭安裝實(shí)現(xiàn)監(jiān)控功能
智能家居 (10) ——人臉識(shí)別祥云平臺(tái)編程使用
智能家居 (11) ——樹(shù)莓派攝像頭捕捉人臉并識(shí)別
智能家居 (12) ——人臉識(shí)別整合到智能家居系統(tǒng)
智能家居 (13) ——智能家居加入手機(jī)app端控制
總結(jié)
以上是生活随笔為你收集整理的智能家居 (7) ——网络服务器线程控制的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: BZOJ-1045 糖果传递
- 下一篇: html网页跳转代码大全