基于ARM的智能灯光控制系统总结(7-主控端网络监听、连接及控制线程)

本文总结了基于ARM的智能灯光控制系统,重点讲述主控进程如何通过网络线程监听客户端连接,建立通信后实现设备状态查询与控制功能。
摘要由CSDN通过智能技术生成

主控进程中开启的网络线程用于监听客户端的连接请求、连接成功后通过网络协议同客户端通信,比如查询客户端设备的在线状态、控制其开关状态等。

net_pro.h

#ifndef __SL2000_NET_H_
#define __SL2000_NET_H_
#define DEF_PORT 6899

int socket_init(int port);
void * client_pro(void * arg);
void * net_pro(void * arg);
int send_cmd(char cmd,char cmd_da,int sockfd);
int get_cmd(char * buf,char *cmd,int len);

#endif

net_pro.c

#include <errno.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <pthread.h>
#include "config.h"
#include "net_pro.h"

int net_user;
unsigned char net_cmd;
unsigned char net_flag;

extern struct sys_all g_dev[1];
extern struct dev_fd g_dev_fd;

int socket_init(int port)
{
	int sockfd;
	struct sockaddr_in server_addr;
	if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
		fprintf(stderr,"Socket error:%s\n\a",strerror(errno));
		exit(1);
	}
	printf("socket...\n");
	bzero(&server_addr,sizeof(struct sockaddr_in));
	server_addr.sin_family=AF_INET;
	server_addr.sin_addr.s_addr=htonl(INADDR_ANY);
	server_addr.sin_port=htons(port);
	if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1){
		fprintf(stderr,"Bind error:%s\n\a",strerror(errno));
		exit(1);
	}
	printf("bind...\n");
	if(listen(sockfd,10)==-1){
		fprintf(stderr,"Listen error:%s\n\a",strerror(errno));
		exit(1);
	}
	printf("listen...\n");
	return sockfd;		
}

//protocol 协议
//-- head---   cmd   data   crc
//0x5a 0x15    0x--   0x--  0x--
int get_cmd(char * buf, char * cmd, int len)
{
	char crc=0;
	int i;
	if(buf==NULL||cmd==NULL||len!=5) return -1;
	if(buf[0]!=0x5a||buf[1]!=0x15)return -1;
	for(i=0;i<len-1;i++){crc+=buf[i];}
	if(crc!=buf[len-1])return -1;
	cmd[0]=buf[2];
	cmd[1]=buf[3];
	return 0;
}

int send_cmd(char cmd, char cmd_da, int sockfd)
{
	unsigned char buf[8];
	if(sockfd<0)return -1;
	buf[0]=0x5a;
	buf[1]=0x15;
	buf[2]=cmd;
	buf[3]=cmd_da;
	buf[4]=buf[0]+buf[1]+buf[2]+buf[3];
	if(send(sockfd,buf,5,0)==-1){
		fprintf(stderr,"Write error:%s\n",strerror(errno));
		return -1;
	}
	return 0;
}

void *client_pro(void * arg)
{
	int fd,*p;
	int len,index;
	int timer=0;
	unsigned char recv_buf[8],cmd[8],old_cmd;

	p=(int *)arg;
	fd=*p;
	net_user++;
	index=net_user-1;
	net_flag=1;//在线 
	g_dev_fd.net_fd[index]=fd;
	old_cmd=net_cmd;//net_cmd的值在sw_pro线程中动态修改

	while(1){
		bzero(recv_buf,8);
		bzero(cmd,8);
		if(timer=3){//好方法,while循环中的定时器,3秒一次
			timer=0;
			send_cmd(0x10,0x11, fd);//查询设备是否在线
			len=recv(fd,recv_buf,8,0);
			if(len==0||len==-1){
				net_user--;
				close(fd);
				net_flag=0;//下线
				g_dev_fd.net_fd[index]=-1;
				pthread_exit("0");
			}else{
				get_cmd(recv_buf,cmd,len);
				if(cmd[0]==0x20&&cmd[1]==0x21)
					net_flag=1;
				else
					net_flag=0;
				printf("\nbuf=%x,%x,%x,%x,%x---cmd=%x,%x----\n",
					recv_buf[0],recv_buf[1],recv_buf[2],recv_buf[3],recv_buf[4],cmd[0],cmd[1]);					
			}
			
		}
		if(old_cmd!=net_cmd){
			old_cmd=net_cmd;
			send_cmd(0x30,old_cmd,fd);//发送开关命令  
		}
		sleep(1);
		timer++;
	}
}

void * net_pro(void * arg)
{
	pthread_t pth;
	int sockfd,new_fd,sin_size;
	struct sockaddr_in client_addr;
	printf("net server pthread start...\n");
	sockfd=socket_init(DEF_PORT);
	printf("sockfd=%d\n",sockfd);
	while(1){
		printf("accept before...\n");
		sin_size=sizeof(struct sockaddr_in);
		new_fd=accept(sockfd,(struct sockaddr *)(&client_addr),&sin_size);
		if(new_fd==-1){
			fprintf(stderr,"Accept error:%s\n\a",strerror(errno));
			pthread_exit("0");
		}
		//输出到屏幕,无缓冲,来一个字符就立马输出
		fprintf(stderr,"Server from:%s\n\a",inet_ntoa(client_addr.sin_addr));
		if(net_user<MAX_NET)
			pthread_create(&pth,NULL,client_pro,(void*)&new_fd);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值