wifi智能小车项目,服务器端主要是基于路由板上跑一个openwrt操作系统。openwrt配置ser2net、mjpg-stream两个软件,同时配置json、sqlite3;
ser2net-----通过wifi接受上位机发送的指令,将数据原封不动的网口转串口,发给下位机处理;
mjpg-stream-----通过usb输入的视频数据流进行编码,通过wifi通道给上位机解码,输出视屏;
json-----解析上位机发送的json包信息;
sqlite3----将解析的上位机发送的密码和账号插入数据库,每次遍历数据库看是否存在账号,不存在则注册;
------------------------------------------------------------------------------------------------------------
这里就简单的把代码拿出来吧,openwrt的系统裁剪和移植还有交叉编译工具链在没有文档下,花了很多时间,由于细节太多,有需要的可以私聊;
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <json/json.h>
#include <sqlite3.h>
#include <string.h>
/****************************************************************/
#define REGISER 0
#define LOGIN 1
int buf0[]={0};
int buf1[]={1};
void handler_message(int signum)
{
waitpid(-1,NULL,WNOHANG);//非阻塞
return;
}
void do_register(int sockfd,sqlite3 *pdb,char *_username,char *_password,char *filename)
{
int ret=0;
char sql[1024]={0};
int nrow=0,ncolumn=0;
char *errmsg;
char **dbresult;
sprintf(sql,"select *from userinfo where userName='%s';",_username);
ret=sqlite3_open(filename,&pdb);
if(ret!=SQLITE_OK)
{
fprintf(stderr,"fail to sqlite3_open:%s\n",sqlite3_errmsg(pdb));
return ;
}
if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg)!=0)
{
fprintf(stderr,"sqlite3 get table error:%s\n",errmsg);
return ;
}
/***********查询若用户不存在*****************/
if(nrow==0)/*******注册**********/
{
bzero(sql,sizeof(sql));
sprintf(sql,"insert into userinfo values('%s','%s');",_username,_password);
sqlite3_exec(pdb,sql,NULL,NULL,&errmsg);
// printf("ok.....\n");
if(send(sockfd,buf1,sizeof(buf1),0)<0)
{
perror("fail to send");
return ;
}
}
/************查询若用户名存在***************/
else
{
if(send(sockfd,buf1,sizeof(buf1),0)<0)
{
perror("fail to send");
return ;
}
}
sqlite3_free_table(dbresult);
}
void do_login(int sockfd,sqlite3 *pdb,char *_username,char *_password,char *filename)
{
int ret=0;
char sql[1024]={0};
int nrow=0,ncolumn=0;
char *errmsg;
char **dbresult;
sprintf(sql,"select *from userinfo where userName='%s';",_username);
ret=sqlite3_open(filename,&pdb);
if(ret!=SQLITE_OK)
{
fprintf(stderr,"fail to sqlite3_open:%s\n",sqlite3_errmsg(pdb));
return ;
}
/************查询查数据表****************/
if(sqlite3_get_table(pdb,sql,&dbresult,&nrow,&ncolumn,&errmsg)!=0)
{
fprintf(stderr,"sqlite3 get table error:%s\n",errmsg);
return ;
}
/***********用户不存在*****************/
if(nrow==0)
{
if(send(sockfd,buf0,sizeof(buf0),0)<0)
{
perror("fail to send");
return ;
}
}
/************用户名存在***************/
else
{
if(send(sockfd,buf1,sizeof(buf1),0)<0)
{
perror("fail to send");
return ;
}
}
sqlite3_free_table(dbresult);
return;
}
void do_client(int sockfd)
{
int n = 0;
unsigned char buf[1024]={0};
json_object *obj;//定义json对象
char _username[25];
char _password[25];
int ret=0;
char sql[1024]={0};
char *errmsg;
char **dbresult;
sqlite3 *pdb=NULL;
char* filename = "/home/ubuntu/project/carinfo.db";
while(1)
{
bzero(buf,sizeof(buf));
n = recv(sockfd,buf,sizeof(buf),0);
if(n <= 0)
{
perror("fail to recv");
exit(EXIT_FAILURE);
}
/***json解析***/
printf("recv_buf= %s\n",buf);//接受对方发来的JSON对象
printf("buf[0]=%d\n",buf[0]);
obj=json_tokener_parse(buf+1);//解析json对象
json_object *new_object=json_object_object_get(obj,"userName");//根据键名获取小对象
printf("%s\n",json_object_get_string(new_object));//获取json对象里的字符串
strcpy(_username,json_object_get_string(new_object));
new_object=json_object_object_get(obj,"passWord");//根据键名获取小对象
printf("%s\n",json_object_get_string(new_object));//获取json对象里的字符串
strcpy(_password,json_object_get_string(new_object));
/***SQL*******/
sprintf(sql,"select *from userinfo where userName='%s';",_username);
ret=sqlite3_open(filename,&pdb);
if(ret!=SQLITE_OK)
{
fprintf(stderr,"fail to sqlite3_open:%s\n",sqlite3_errmsg(pdb));
return ;
}
/***登录******/
if(buf[0]=='1')
{
do_login(sockfd,pdb,_username,_password,filename);
}
/***注册*****/
else if(buf[0]=='2')
{
do_register(sockfd,pdb,_username,_password,filename);
}
exit(EXIT_SUCCESS);
}
//./a.out ip port
int main(int argc, const char *argv[])
{
int listen_fd;
int connect_fd;
struct sockaddr_in ser_addr;
struct sockaddr_in client_addr;
socklen_t len = sizeof(struct sockaddr);
int n = 0;
char buf[1024] = {0};
pid_t pid;
if(argc != 3)
{
fprintf(stderr,"Uage: %s ip port ",argv[0]);
exit(EXIT_FAILURE);
}
if(signal(SIGCHLD,handler_message) == SIG_ERR)
{
perror("fail to signal");
exit(EXIT_FAILURE);
}
//1.创建一个监听套接字
listen_fd = socket(AF_INET,SOCK_STREAM,0);
if(listen_fd < 0)
{
perror("fail to socket");
exit(EXIT_FAILURE);
}
//2.服务器地址赋值
bzero(&ser_addr,len);
ser_addr.sin_family = AF_INET;
ser_addr.sin_port = htons(atoi(argv[2]));
ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
//3.绑定套接字
if(bind(listen_fd,(struct sockaddr *)&ser_addr,len) < 0)
{
perror("fail to bind");
exit(EXIT_FAILURE);
}
//4.打开监听,设置监听队列的长度10
listen(listen_fd,10);
printf("listen ......I\n");
while(1)
{
connect_fd = accept(listen_fd,(struct sockaddr *)&client_addr,&len);
if(connect_fd < 0)
{
perror("fail to accept");
exit(EXIT_FAILURE);
}
printf("----------------------------------------------------");
printf("connect_fd = %d\n",connect_fd);
printf("client_addr.sin_port = %d\n",ntohs(client_addr.sin_port));
printf("client_addr.sin_addr = %s\n",inet_ntoa(client_addr.sin_addr));
//
pid = fork();
if(pid < 0)
{
perror("fail to fork");
exit(EXIT_FAILURE);
}else if(pid == 0) //子进程负责数据的接收
{
do_client(connect_fd);
close(listen_fd);
}else{
close(connect_fd);
}
}
return 0;
}
}