网络客户端即为tiny6410,其运行一个独立的程序,该程序控制其连接的灯光、感应、继电器等设备。
通过连接服务器的ip及端口,同服务器建立链接,反馈服务器的查询命令,根据服务器传来的控制命令操作灯光等设备。
net_light.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#define DEV_6410RELAY "/dev/6410_relay"
#define DEV_6410PIR "/dev/6410_hongwai"
#define J1_OFF 0X01
#define J1_ON 0X00
#define BUF_SIZE 32
int fd_relay=-1;
int fd_pir=-1;
int dev_init()
{
printf("Tiny6410 driver init...\n");
fd_relay=open(DEV_6410RELAY,O_RDWR);
if(fd_relay<0){
printf("open 6410relay device err\n");
return -1;
}
fd_pir=open(DEV_6410PIR,O_RDWR);
if(fd_pir<0){
printf("open 6410pir device err\n");
return -1;
}
}
int net_init(char * ip,char * port_str)
{
int sockfd,port;
struct sockaddr_in server_addr;
port=atoi(port_str);//atoi(const char * p)将字符串转化为整型数据,
//反义函数itoa(int value,char * string, int radix)
if(port<1024){
printf("port error\n");
return -1;
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1){
fprintf(stderr,"Socket Error:%s\a\n",strerror(errno));
return -1;
}
bzero(&server_addr,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(port);
server_addr.sin_addr.s_addr=inet_addr(ip);
if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1){
fprintf(stderr,"Connect Error:%s\a\n",strerror(errno));
return -1;
}
return sockfd;
}
void dev_sw(int sw)
{
char da[2];
if(sw==3){ //根据红外传感器状态设定灯光开关
read(fd_pir,da,1);
write(fd_relay,da,1);
}else{ //根据网络命令设定灯光开关
if(sw==1){da[0]=J1_ON;}
if(sw==2){da[0]=J1_OFF;}
write(fd_relay,da,1);
}
printf("---sw=%d---\n",sw);
}
//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 cmd_proc(char *cmd,int sockfd)
{
char buf[8];
buf[0]=0x5a;
buf[1]=0x15;
if(cmd==NULL||sockfd<0) return -1;
if(cmd[0]==0x10){ //回复服务器发来的查询命令,网络设备在线
buf[2]=0x20;
buf[3]=0x21;
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));
}
if(cmd[0]==0x30){ //服务器发来设备控制命令
switch(cmd[1]){
case 0x31://ON
dev_sw(2);
break;
case 0x32://OFF
dev_sw(1);
break;
case 0x33://auto
dev_sw(3);
break;
}
}
if(cmd[0]==0){
dev_sw(1);
printf("nanopi command error\n");
}
return 0;
}
int main(int argc,char *argv[]) //argc保存参数个数,字符串数组保存参数内容
{
int sockfd=-1;
int nbytes=0;
char recv_buf[BUF_SIZE],cmd[2];
if(argc<3){
printf("Please input ip and port\n");
exit(0);
}
if(dev_init()<0){
exit(0);
}
if((sockfd=net_init(argv[1],argv[2]))<0){
exit(0);
}
dev_sw(2);//初始灯是亮的
while(1){
bzero(recv_buf,BUF_SIZE);
bzero(cmd,2);
if((nbytes=recv(sockfd,recv_buf,BUF_SIZE,0))==-1){
fprintf(stderr,"Read Error:%s\n",recv_buf);
exit(1);
}
if(nbytes>=5){
if(get_cmd(recv_buf,cmd,nbytes)==0) cmd_proc(cmd,sockfd);
//get_cmd(recv_buf,cmd,nbytes);
//cmd_proc(cmd,sockfd);
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]);
}
//sleep(1); 这句话很重要,不注释掉的话则客户端运行非常不正常,十分容易卡死,不知道为什么??
}
return 0;
}
客户端程序的makefile文件如下
#Make the main program
CC=arm-linux-gcc
OBJ=net_light.c
CFLAGS= -w -g -o2
net_light:$(OBJ)
$(CC) $(CFLAGS) -o $@ $^
install:
cp net_light /home/tmp/net/
clean:
rm -f ./*.o