注意:本项目的所有代码中,仅客户端的代码是开源的,其他功能的实现仅给出大致的解决方法,代码则闭源。客户端的程序,仅可以在Linux系统上运行。
开发器材:
安装有温度传感器的树莓派开发板一块、开通有公网IP服务的路由器一台(最好在阿里云上注册有域名)、电源、网线。
Unix环境高级编程的基本内容,包括文件I/O、socket网络编程初步、多进程编程、多线程编程等;sqlite3 数据库基本命令的使用和对应的C接口函数的应用。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUF_SIZE 256
#define IP_LEN 32
#define LOG_PATH "./send.log"
void dns(char *domain_name, char **ip);
void dns(char *domain_name, char **ip)
{
struct hostent *server_name = NULL;
server_name = gethostbyname(domain_name);
inet_ntop(server_name->h_addrtype, server_name->h_addr, *ip, 32 );
}
int main(int argc, char **argv)
{
int bind_fd = -1;
int read_fd = -1;
int server_fd = -1;
int connect_fd = -1;
int send_id = -1;
int opt = -1;
char buf[BUF_SIZE];
char *server_ip = (char *)malloc(IP_LEN);
struct sockaddr_in server_addr;
opt = getopt(argc, argv, "xy");
if( opt!='x' && opt!= 'y' )
{
printf("temperGet usage:\n-s: read the temperature from XXX pi\n-m: read the temperature from YYY pi\n\n");
return -1;
}
if(opt == 'x')
{
dns("XXX.XXX.com", &server_ip);
}
else
{
dns("YYY.YYY.com", &server_ip);
}
server_fd = socket( AF_INET, SOCK_STREAM, 0);
if(server_fd < 0)
{
printf("Fail to create a client socket [%d]: %s\n", server_fd, strerror(errno) );
return 0;
}
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
if(opt == 'x')
{
server_addr.sin_port = htons(6666);
printf("Get temperature from XXX.XXX.com...\n");
}
else
{
server_addr.sin_port = htons(8888);
printf("Get temperature from YYY.YYY.com...\n");
}
inet_aton(server_ip, &server_addr.sin_addr);
connect_fd = connect(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr) );
if(connect_fd < 0)
{
printf("Fail to connect sever!IP:%s error:%s\n\n", inet_ntoa(server_addr.sin_addr), strerror(errno) );
return 0;
}
memset(buf, 0, sizeof(buf) );
read_fd = read(server_fd, buf, sizeof(buf) );
if(read_fd < 0)
{
printf("Fail to get temperature [%d]: %s\n", read_fd, strerror(errno) );
return 0;
}
else
{
printf("%s\n\n",buf);
}
memset(buf, 0, BUF_SIZE);
send_id = open(LOG_PATH, O_CREAT|O_TRUNC|O_RDWR, 0666);
if(send_id < 0)
{
printf("Fail to create a new file to record the client message :%s\n", strerror(errno));
return -1;
}
dup2(send_id, STDOUT_FILENO);
system("echo `date`; who | sed -n '$p'; uname -a");
lseek(send_id, SEEK_SET, 0);
if( (read(send_id, buf, BUF_SIZE)) < 0)
{
printf("Fali to read the file :%s :%s\n", LOG_PATH, strerror(errno));
return -1;
}
if( (write(server_fd, buf, BUF_SIZE)) < 0)
{
printf("Fail to write the server socket fd :%s\n", strerror(errno));
return -1;
}
unlink(LOG_PATH);
close(send_id);
close(server_fd);
close(read_fd);
close(connect_fd);
return 0;
}
简要说明一下客户端的程序逻辑:
以上是客户端的代码,若是读者有看不懂的函数或不知道相关函数的使用方法,请自行利用搜索引擎或是利用Linux中man手册进行查询。