目錄
- 1.工廠模式創建網路控制物件:
- (1)socketControl.c 檔案(網路控制)
- (2)command.h 檔案(指令方式類)
- 2.多執行緒控制——網路控制(除錯):
- (1)main.c 檔案(主函式)
- (2)除錯
- 3.往期文章:
1.工廠模式創建網路控制物件:
(1)socketControl.c 檔案(網路控制)
#include "command.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); //“網路控制”功能初始化函式宣告
struct Command *addSocketControlToLink(struct Command *phead); //“網路控制”(物件)加入指令鏈表函式宣告
struct Command socketControl = { //定義“網路控制”物件
.commandName = "socketControl", //名字
.command = {'\0'}, //初始化儲存“指令”的空間
.Init = socketControlInit, //指定“網路控制”功能初始化函式
.ipAdress = "192.168.137.110", //樹莓派 IP地址
.port = "8888", //打開的埠號
};
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); //創建套接字
if(s_fd == -1){ //若創建套接字失敗
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){ //套接字與埠號系結
perror("bind error");
exit(-1);
}
if(listen(s_fd,10) == -1){ //打開監聽
perror("listen error");
exit(-1);
}
file->s_fd = s_fd; //發送套接字描述符
}
struct Command *addSocketControlToLink(struct Command *phead) //“網路控制”(物件)加入指令鏈表函式
{
if(phead == NULL){
return &socketControl;
}else{
socketControl.next = phead;
phead = &socketControl;
return phead;
}
}
(2)command.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; //存放檔案描述符
void (*Init)(struct Command *file); //“初始化”函式指標
int s_fd; //存放套接字描述符
char ipAdress[32]; //存放 IP地址
char port[12]; //存放埠號
int (*getCommand)(struct Command *cmd); //“獲取指令”函式指標
struct Command *next;
};
struct Command *addSocketControlToLink(struct Command *phead); //“網路控制”加入指令鏈表函式宣告
2.多執行緒控制——網路控制(除錯):
(1)main.c 檔案(主函式)
僅除錯
#include <stdio.h>
#include <string.h>
#include "equipment.h"
#include "command.h"
#include <pthread.h>
#include <unistd.h>
struct Command *findCommandByName(char *name,struct Command *phead); //尋找鏈節函式宣告
void *socketControlThread(void *data); //“網路控制”執行緒函式宣告
void *socketReadThread(void *data); //“讀取埠”執行緒函式宣告
struct Command *cmdhead = NULL; //創建“指令”鏈表全域變數
struct Command *socketHandler = NULL; //創建“鏈節處理”全域變數
int main()
{
cmdhead = addSocketControlToLink(cmdhead); //“網路控制”物件加入鏈表
pthread_t socketControl_thread;
pthread_create(&socketControl_thread,NULL,socketControlThread,NULL); //創建“網路控制”執行緒
pthread_join(socketControl_thread, NULL); //主函式等待“網路控制”執行緒退出
return 0;
}
void *socketControlThread(void *data) //“網路控制”執行緒
{
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; //存放執行緒 ID
socketHandler = findCommandByName("socketControl",cmdhead); //尋找并回傳“網路控制”所處鏈節
if(socketHandler == NULL){ //若找不到
printf("find socketHandler error\n");
pthread_exit(NULL);
}
if(socketHandler->Init(socketHandler) < 0){ //執行“網路控制”功能初始化函式
printf("socketControl init error\n");
pthread_exit(NULL);
}
while(1){
c_fd = accept(socketHandler->s_fd,(struct sockaddr*)&c_addr,&clen); //接收連接請求
socketHandler->fd = c_fd; //發送檔案描述符
pthread_create(&socketRead_thread,NULL,socketReadThread,NULL); //創建“讀取埠”執行緒
}
}
void *socketReadThread(void *data) //“讀取埠”執行緒
{
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); //讀取成功,列印資料
}
}
struct Command *findCommandByName(char *name,struct Command *phead) //通過“名字”尋找鏈節函式
{
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;
}
(2)除錯
工具:NetAssist

①選擇相應選項:
(協議型別)
(樹莓派 IP 地址)
(打開監聽的埠號)

②樹莓派運行除錯函式:

③點擊連接,并發送內容Hello:

樹莓派終端:

④點擊斷開,再次連接,并發送內容HAHAHAHA:

樹莓派終端:

3.往期文章:
智能家居 (1) ——工廠模式繼電器控制燈
智能家居 (2) ——工廠模式火焰報警器
智能家居 (3) ——語音識別控制(執行緒)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/263009.html
標籤:其他
