Linux--socket温度上报练习

socket温度上报练习

在这里插入图片描述
通过读取文件“t=”后的内容/1000得到实时温度
文件io操作:

//读取温度值
int get_temper(float *temp,FILE *fp)  //FILE参数用于记录日志
{
	int fd;
	char *ptr;
	int rd;
	char buf[1024];
	char file_path[50] = TPATH;
	DIR *dirp;
	struct dirent *direntp;
	int found = -1;
	char chip[20];
	dirp=opendir(file_path);
	if(dirp==NULL)
	{
		fprintf(fp,"打开文件夹失败:%s",strerror(errno));
		goto cleanup;
	}
	while((direntp=readdir(dirp))!=NULL)    //循环遍历文件夹名字,找到“28-”文件夹
	{
		if(strstr(direntp->d_name,"28-"))
		{
			strcpy(chip,direntp->d_name);
			found=1;
			break;
		}
	}
	strcat(file_path,chip);
	strcat(file_path,"/w1_slave");

	fd=open(file_path,O_RDONLY,644);
	if(fd<0)
	{
		fprintf(fp,"打开文件失败:%s\n",strerror(errno));
		return -1;
	}
	rd=read(fd,buf,sizeof(buf));
	close(fd);
	ptr=strstr(buf,"t=");
	ptr+=2;
	*temp=(atof(ptr)/1000.0);
cleanup:
	closedir(dirp);
	if(!found)
	{
		fprintf(fp,"找不到设备\n");
	}
	return 0;
}

socket上报,涉及域名解析,参数解析:(关于gethostbyname()函数详细点击

int get_parameter(int argc,char **argv,int *port,char *ip)
{
	char *_argv[argc];
	int optret = 0;
	char ipArry[1024];
	for(int i=0;i<argc;i++)
		_argv[i] = *(argv+i);
	while((optret =getopt(argc,_argv,"i:p:"))!=-1)
	{
		switch(optret)
		{
			case 'i':
				if(get_ip(optarg,ipArry)<0)
					strncpy(ip,optarg,sizeof(ipArry));
				strncpy(ip,ipArry,sizeof(ipArry));
				break;
			case 'p':
				*port = atoi(optarg);
				break;
			default:
				printf("输入格式:./client -p [port] -i [ip or hostname]\n");
				break;
		}
	}
		if(*port==0||*ip==0)
			return -1;
		return 1;
}
int get_ip(char *hostname,char *buf)
{
	char *ipaddr = NULL;
	struct hostent *gethost;
	gethost = gethostbyname(hostname);
	char ip[100];
	if (NULL == gethost)
	{
		return -1;
	}
	memset(ip,0,sizeof(ip));
	ipaddr = (char *)inet_ntop(gethost->h_addrtype,gethost->h_addr_list[0],ip,sizeof(ip));
	strncpy(buf,ipaddr,sizeof(ip));
	return 0;
}

要求程序在Linux后台运行,使用deamon()函数创建守护进程,守护进程需要自己的日志系统记录程序运行情况:

FILE *my_syslog(char *buf)
{
	FILE *fp;
	mode_t mode = umask(0);
	if(access("./log/",F_OK)==0)
		goto um;
	if(mkdir("./log/",0755)<0)
	{
		printf("创建日志文件夹失败:%s\n",strerror(errno));
		return NULL;
	}
um:
	umask(mode);
	fp = fopen(SYSLOG,"a+");
	if(NULL==fp)
		printf("打开日志文件失败:%s\n",strerror(errno));
	if(setvbuf(fp,buf,_IOLBF,128)!=0)
		return NULL;
	return fp;
}
void my_syslog_close(FILE *fp)
{
	fprintf(fp,"关闭日志文件!\n");
	fclose(fp);
}

socket上报,需要了解socket相关知识
在这里插入图片描述

//服务器连接
int connect_server (char *ip,int port,FILE *fp)
{
	int sockfd = -1;
	struct sockaddr_in cli_addr;
	sockfd = socket(AF_INET,SOCK_STREAM,0);
	if (sockfd < 0)
	{
		fprintf(fp,"socket初始化失败:%s\n",strerror(errno));
		return -1;
	}
	memset(&cli_addr,0,sizeof(cli_addr));
	cli_addr.sin_family= AF_INET;
	cli_addr.sin_port = htons((uint16_t)(port));
	inet_aton(ip,&cli_addr.sin_addr);
	fprintf(fp,"准备连接%s\n端口%d\n",ip,port);
	if ((connect(sockfd,(struct sockaddr *)&cli_addr,sizeof(cli_addr))) < 0)
	{
		fprintf(fp,"连接到:%s 端口:%d 失败:%s\n",ip,port,strerror(errno));
		return -1;
	}
	return sockfd;
}

、、
在这里插入图片描述由于是多个c文件编写,需要了解程序编译过程这篇博客可以借鉴点击
编写makefile文件可以:
a. 管理代码的编译,决定该编译什么文件,编译顺序,以及是否需要重新编译;

b. 节省编译时间。如果文件有更改,只需重新编译此文件即可,无需重新编译整个工程;

c. 一劳永逸。Makefile通常只需编写一次,后期就不用过多更改。
本次程序结构并不是很复杂,我的makefile:

src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src))
target = client
CC = gcc
$(target):$(obj)
	@$(CC) $(obj) -o $(target) -Wall
%.o:%.c
	@$(CC) -c $< -o $@ 
clean:
@rm -rf *.o

完整代码在github站点存放点击查看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值