要求:
1、从配置文件中读取数据;
2、编写可滚动的日志文件;
3、实现非阻塞套接字,应用epoll;
4、实现心跳检测(心跳包);
5、分线程处理
client.c 客户机程序
#include "head.h"
#include "config.h"
#include "heart_client.h"
#define BUFFER_SIZE 40
int main(int argc, char *argv[])
{
int client_sockfd;
int len;
struct sockaddr_in remote_addr; // 服务器端网络地址结构体
memset(&remote_addr,0,sizeof(remote_addr)); // 数据初始化--清零
remote_addr.sin_family=AF_INET; // 设置为IP通信
char s_ip[20];
GetConfigFileStringValue("IPANDPORT", "IP", "127.0.0.1", s_ip, sizeof(s_ip), "Config.ini");
printf("IP : %s\n", s_ip);
remote_addr.sin_addr.s_addr=inet_addr(s_ip);// 服务器IP地址
uint16_t port = GetConfigFileIntValue("IPANDPORT", "PORT", 8866, "Config.ini");
printf("port : %d\n", (int)port);
if (port == -1){ // 判断获取到的年龄是否正确
printf("Get port failed!\n");
return -1;
}
remote_addr.sin_port=htons(port); // 服务器端口号
// 创建客户端套接字--IPv4协议,面向连接通信,TCP协议
client_sockfd=socket(AF_INET,SOCK_STREAM,0);
if(client_sockfd<0){
perror("client socket creation failed");
exit(EXIT_FAILURE);
}
// 将套接字绑定到服务器的网络地址上
if((connect(client_sockfd,(struct sockaddr *)&remote_addr,sizeof(struct sockaddr)))<0){
perror("connect to server failed");
exit(EXIT_FAILURE);
}
pthread_t pth;
int err;
int *client_sockfd_1 = (int *)malloc(sizeof(int));
*client_sockfd_1 = client_sockfd;
if((err = pthread_create(&pth, NULL, send_heart, (void *)client_sockfd_1)) != 0){
fprintf(stderr, "pthread_create: %s\n", strerror(err));
exit(1);
}
sleep(5);
// 循环监听服务器请求
pd = (DATA_PACK *)malloc(sizeof(DATA_PACK));
char *buf = (char *)malloc(sizeof(*pd));
pd->data_type=8;
strcpy(pd->name, "127.0.0.1");
pd->num1= (int )GetConfigFileIntValue("TWONUMBER", "NUMBER1", 0x3f3f3f3f, "Config.ini");
pd->num2 = (int )GetConfigFileIntValue("TWONUMBER", "NUMBER2", 0x3f3f3f3f, "Config.ini");
printf("两个数为:%d %d\n",pd->num1,pd->num2);
len = sizeof(*pd);
memcpy(buf, pd, len);
send(client_sockfd,buf,len,0);
// 接收服务器端信息
len=recv(client_sockfd,pd,BUFFER_SIZE,0);
if(pd->data_type==8)
printf("receive from server %s: %d\n",pd->name,pd->num1);
else
printf("receive from server %s: 发送数字个数不正确\n",pd->name);
if(len<0)
{
perror("receive from server failed");
exit(EXIT_FAILURE);
}
free(pd);
close(client_sockfd);// 关闭套接字
return 0;
}
config.c //实现获取配置文件中的内容
#include "config.h"
// 功能描述: 获取配置文件完整路径(包含文件名)
// 输入参数: pszConfigFileName-配置文件名
// pszWholePath-配置文件完整路径(包含文件名)
void GetCompletePath(UINT8 *pszConfigFileName, UINT8 *pszWholePath){
UINT8 *pszHomePath = NULL;
UINT8 szWholePath[256] = {0};
// 先对输入参数进行异常判断
if (pszConfigFileName == NULL || pszWholePath == NULL){
printf("GetCompletePath: input parameter(s) is NULL!\n");
return;
}
pszHomePath = (UINT8 *)getenv("HOME"); // 获取当前用户所在的路径
if (pszHomePath == NULL){
printf("GetCompletePath: Can't find home path!\n");
return;
}
// 拼装配置文件路径
snprintf(szWholePath, sizeof(szWholePath)-1, "%s", pszConfigFileName);
strncpy(pszWholePath, szWholePath, strlen(szWholePath));
}
// 功能描述: 获取具体的字符串值
// 输入参数: fp-配置文件指针
// pszSectionName-段名, 如: GENERAL
// pszKeyName-配置项名, 如: EmployeeName
// iOutputLen-输出缓存长度
// 输出参数: pszOutput-输出缓存
void GetStringContentValue(FILE *fp, UINT8 *pszSectionName, UINT8 *pszKeyName, UINT