用法:
最近在做server app和cloud云通讯。
简单记录tip:
poll的简单使用,记录下。类似于select,不同的是select有最大限制,poll是链表结构。
没有最大限制。
多并发,多访问,用epoll更好。
1.
int local_server_client_fd=-1;//as server and app,send date's fd
//3.listen 监听客户端的connect
if( listen(local_socket_server_fd, LISTEN_MAX) < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket listen failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
2.
struct pollfd pollfds;
memset(&pollfds, 0, sizeof(struct pollfd));
pollfds.fd = local_server_client_fd ;
pollfds.events = POLLIN;
pollfds.revents = 0;
3.
local_server_client_fd = accept(local_socket_server_fd, (struct sockaddr *)&client_addr, &client_addrlen);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
if(local_server_client_fd < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData accept failed\n",__FUNCTION__,__LINE__);
exit(1);
}
4.
pollfds.fd = local_server_client_fd ;
poll_ret = poll(&pollfds, 1, POLL_TIMEOUT);
if (poll_ret < 0)
{
if (errno != EINTR)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) socket poll errno local_server_client_fd=%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
perror ("poll");
break;
}
my_printf(LOG_MODE_LEVEL_3, "%s(%d) socket poll EINTR\n",__FUNCTION__,__LINE__);
}
else if(poll_ret == 0)
{
my_printf(LOG_MODE_LEVEL_5, "%s(%d) socket poll timeoutr.local_server_client_fd=%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
}
else if(poll_ret >0)
{
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,local_server_client_fd:%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,pollfds.revents:is 0x%x\n",__FUNCTION__,__LINE__,pollfds.revents);
if(pollfds.revents & POLLIN) //F30g as a server.The local server is not through the Server.Phone App is connected by WIFI route
{
my_printf(LOG_MODE_LEVEL_1,"%s(%d) F30g as a server\n",__FUNCTION__,__LINE__);
retlocal = HandleSyncAppData(local_server_client_fd,sockfd,local_server_addr);//1.sockfdlocal(The phone app through the soceket,send or get the jason data) 2.sockfd(the f30g through the socket connect the server for send and get jason data)
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleSyncAppData local_socket_server_fd \n",__FUNCTION__,__LINE__);
if (retlocal <= 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleSyncAppData break=%d\n",__FUNCTION__,__LINE__,retlocal);
break;
}
}
}
例子:
void* task_sync_app_as_client_thread()
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
int i=0;
struct pollfd fds[3];
json_object *boot_json =NULL;
boot_json = json_object_new_object();
CHECK_NEW_JSON(boot_json);
char *buffer = NULL;
char *buffer_total = NULL;
int ret=0;
int poll_ret = 0;
PCONFAPP pApp = GetConfAppPointer();
struct sockaddr_in remoter_addr; /* remoter sever socket address*/
bzero(&remoter_addr, sizeof(remoter_addr));
remoter_addr.sin_family = AF_INET; //internet IPV4
remoter_addr.sin_port = htons(TCPPORT);
remoter_addr.sin_addr.s_addr = TCPADDR; //server ip
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
/*local client address*/
//设置一个socket地址结构client_addr,代表客户机(client)的internet地址, 端口
struct sockaddr_in client_addr;
bzero(&client_addr, sizeof(client_addr)); //把一段内存区的内容全部设置为0
client_addr.sin_family = AF_INET; //internet协议族 IPV4
client_addr.sin_addr.s_addr = htons(INADDR_ANY); //INADDR_ANY表示自动获取本机地址
client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
//创建用于internet的流协议(TCP)socket,用client_socket代表client's socket
int client_socket = socket(AF_INET, SOCK_STREAM, 0);
if( client_socket < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket create failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
int opt =1; //超时时间
setsockopt(client_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //用来做超时 https://blog.csdn.net/A493203176/article/details/65438182
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
// 把socket和socket地址结构联系起
if ( bind(client_socket, (struct sockaddr *)&client_addr, sizeof(client_addr)) < 0 )
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket bind failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
/*
connect() 连接后,client_socket描述符即是:server和client交换数据的描述符
*/
socklen_t server_addr_length = sizeof(remoter_addr);
//向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接
//客户端通过调用connect函数来建立与TCP服务器的连接
if(connect(client_socket, (struct sockaddr*)&remoter_addr, server_addr_length) < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) Can Not Connect To....10.28.1.95...\n",__FUNCTION__,__LINE__);
exit(1);
}
my_printf(LOG_MODE_LEVEL_3, " %s(%d) linbo......\n",__FUNCTION__,__LINE__);
BootJson(boot_json);
buffer = (char *)json_object_to_json_string(boot_json);
my_printf(LOG_MODE_LEVEL_1,"%s(%d) buffer:%s\n",__FUNCTION__,__LINE__,buffer);
buffer_total = remove_blank_space_and_update_length(buffer);
my_printf(LOG_MODE_LEVEL_1,"%s(%d) buffer_total:%s\n",__FUNCTION__,__LINE__,buffer_total);
send(client_socket,buffer_total,strlen(buffer_total),0);
//send(client_socket,buffer,strlen(buffer),0);
//SendtoRemoter(sockfd,buffer);
my_printf(LOG_MODE_LEVEL_1,"%s(%d) .......................\n",__FUNCTION__,__LINE__);
struct pollfd pollfds_client;
memset(&pollfds_client, 0, sizeof(struct pollfd));
pollfds_client.fd = client_socket ;
pollfds_client.events = POLLIN;
pollfds_client.revents = 0;
while(1/*pApp->exitflag*/)
{
my_printf(LOG_MODE_LEVEL_1,"confapp remotersocket recv data %s(%d) F30g as a cilent\n",__FUNCTION__,__LINE__);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) client app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
poll_ret = poll(&pollfds_client, 1, POLL_TIMEOUT);
if (poll_ret < 0)
{
if (errno != EINTR)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) socket poll errno client_socket=%d\n",__FUNCTION__,__LINE__,client_socket);
perror ("poll");
break;
}
my_printf(LOG_MODE_LEVEL_3, "%s(%d) socket poll EINTR\n",__FUNCTION__,__LINE__);
}
else if(poll_ret == 0)
{
my_printf(LOG_MODE_LEVEL_5, "%s(%d) socket poll timeoutr.client_socket=%d\n",__FUNCTION__,__LINE__,client_socket);
}
else if(poll_ret >0)
{
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,client_socket:%d\n",__FUNCTION__,__LINE__,client_socket);
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,pollfds.revents:is 0x%x\n",__FUNCTION__,__LINE__,pollfds_client.revents);
if(pollfds_client.revents & POLLIN) //F30g as a client.
{
my_printf(LOG_MODE_LEVEL_1,"%s(%d) F30g as a server\n",__FUNCTION__,__LINE__);
ret = HandleRemoterData(client_socket,fds);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
if (ret <= 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData break=%d\n",__FUNCTION__,__LINE__,ret);
break;
}
}
}
}
return NULL;
}
void* task_sync_app_thread()
{
int i=0;
int retlocal=0;
int sockfd = -1;
int local_server_client_fd=-1;//as server and app,send date's fd
int poll_ret = 0;
struct sockaddr_in local_server_addr;
bzero(&local_server_addr, sizeof(local_server_addr));
local_server_addr.sin_family = AF_INET; //internet IPV4
local_server_addr.sin_port = htons(18889);
local_server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //指定为INADDR_ANY,那么系统将绑定默认的网卡【即IP地址】
PCONFAPP pApp = GetConfAppPointer();
//1.建立socket
//创建用于internet的流协议(TCP)socket,用socket_server_fd代表服务器socket
int local_socket_server_fd = socket(AF_INET, SOCK_STREAM, 0);
if( local_socket_server_fd < 0) //if(socket_server_fd == -1)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket create failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
int opt =1; //超时时间
setsockopt(local_socket_server_fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt)); //用来做超时 https://blog.csdn.net/A493203176/article/details/65438182
//2.bind
// 把socket和socket地址结构联系起
if ( bind(local_socket_server_fd, (struct sockaddr *)&local_server_addr, sizeof(local_server_addr)) < 0 )
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket bind failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
//3.listen 监听客户端的connect
if( listen(local_socket_server_fd, LISTEN_MAX) < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...socket listen failed.......\n",__FUNCTION__,__LINE__);
exit(1);
}
struct pollfd pollfds;
memset(&pollfds, 0, sizeof(struct pollfd));
pollfds.fd = local_server_client_fd ;
pollfds.events = POLLIN;
pollfds.revents = 0;
my_printf(LOG_MODE_LEVEL_1,"pApp->exitflag:%d,fds.fd:%d\n",pApp->exitflag,pollfds.fd);
//4.while(1) 循环 处理收到的请求
while(1)
{
sleep(10);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
//5.accept() 建立server和client的链接,返回一个可用于信息交换的描述符local_server_client_fd
//定义客户端的socket地址结构client_addr
struct sockaddr_in client_addr;
socklen_t client_addrlen = sizeof(client_addr);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
local_server_client_fd = accept(local_socket_server_fd, (struct sockaddr *)&client_addr, &client_addrlen);
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
if(local_server_client_fd < 0)
{
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData accept failed\n",__FUNCTION__,__LINE__);
exit(1);
}
my_printf(LOG_MODE_LEVEL_3, " %s(%d) app_thread...........%d\n",__FUNCTION__,__LINE__, i++);
#if 0
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData local_socket_server_fd 111111111111111111\n",__FUNCTION__,__LINE__);
char buf[APP_BUF_MAX_LEN]; //1024
int nRet,addrlen;
addrlen = sizeof(struct sockaddr_in);
bzero(buf, APP_BUF_MAX_LEN);//数组初始化,清0
nRet = recv(local_server_client_fd, buf, APP_BUF_MAX_LEN, 0);
if (nRet < 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d)Server Recieve Data Failed!\n",__FUNCTION__,__LINE__);
break;
}
my_printf(LOG_MODE_LEVEL_1, "%s(%d) recv buf=%s\n",__FUNCTION__,__LINE__, buf);
nRet = recvfrom(local_socket_server_fd,buf,APP_BUF_MAX_LEN,0,(struct sockaddr *)&local_server_addr,&addrlen);
if (nRet < 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d)Server Recieve Data Failed!\n",__FUNCTION__,__LINE__);
break;
}
my_printf(LOG_MODE_LEVEL_4, "%s(%d) recv buf=%s\n",__FUNCTION__,__LINE__, buf);
#endif
// retlocal = HandleSyncAppData(local_server_client_fd,sockfd,local_server_addr);//1.sockfdlocal(The phone app through the soceket,send or get the jason data) 2.sockfd(the f30g through the socket connect the server for send and get jason data)
// my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData local_socket_server_fd 222222222222222222\n",__FUNCTION__,__LINE__);
pollfds.fd = local_server_client_fd ;
poll_ret = poll(&pollfds, 1, POLL_TIMEOUT);
if (poll_ret < 0)
{
if (errno != EINTR)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) socket poll errno local_server_client_fd=%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
perror ("poll");
break;
}
my_printf(LOG_MODE_LEVEL_3, "%s(%d) socket poll EINTR\n",__FUNCTION__,__LINE__);
}
else if(poll_ret == 0)
{
my_printf(LOG_MODE_LEVEL_5, "%s(%d) socket poll timeoutr.local_server_client_fd=%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
}
else if(poll_ret >0)
{
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,local_server_client_fd:%d\n",__FUNCTION__,__LINE__,local_server_client_fd);
my_printf(LOG_MODE_LEVEL_4, "%s(%d) POLLIN,pollfds.revents:is 0x%x\n",__FUNCTION__,__LINE__,pollfds.revents);
if(pollfds.revents & POLLIN) //F30g as a server.The local server is not through the Server.Phone App is connected by WIFI route
{
my_printf(LOG_MODE_LEVEL_1,"%s(%d) F30g as a server\n",__FUNCTION__,__LINE__);
retlocal = HandleSyncAppData(local_server_client_fd,sockfd,local_server_addr);//1.sockfdlocal(The phone app through the soceket,send or get the jason data) 2.sockfd(the f30g through the socket connect the server for send and get jason data)
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleSyncAppData local_socket_server_fd \n",__FUNCTION__,__LINE__);
if (retlocal <= 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleSyncAppData break=%d\n",__FUNCTION__,__LINE__,retlocal);
break;
}
}
}
//retlocal = HandleClientData(local_socket_server_fd);//1.sockfdlocal(The phone app through the soceket,send or get the jason data) 2.sockfd(the f30g through the socket connect the server for send and get jason data)
#if 1
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleData local_socket_server_fd 333333333333333333333\n",__FUNCTION__,__LINE__);
if (retlocal <= 0)
{
my_printf(LOG_MODE_LEVEL_1, "%s(%d) HandleSyncAppData return error. break=%d\n",__FUNCTION__,__LINE__,retlocal);
break;
}
#endif
}
return NULL;
}