这篇博客我们主要分析thermal-engine的socket监控,包括应用client的注册回调,以及client发送thermal消息都是通过socket。在thermal-engine启动分析的时候我们看到其创建了4个socket。
1. socket初始化
我们从main函数的thermal_server_init函数分析,这个函数其实流程很简单,对创建的4个socket,thermal-engine是server端,要bind listen,最后创建了一个thead进行各个socket的收发工作。这个thread的函数是
int thermal_server_init(void)
{
...
#ifdef ANDROID
sockfd_server_send = android_get_control_socket(
THERMAL_SEND_SOCKET_NAME);
if (sockfd_server_send > -1) {
sockfd_server_recv = android_get_control_socket(
THERMAL_RECV_SOCKET_NAME);
if (sockfd_server_recv < 0)
goto error;
sockfd_server_recv_passive = android_get_control_socket(
THERMAL_RECV_PASSIVE_SOCKET_NAME);
if (sockfd_server_recv_passive < 0)
goto error;
sockfd_server_rule = android_get_control_socket(
THERMAL_SEND_RULE_SOCKET_NAME);
if (sockfd_server_rule < 0)
goto error;
}
#endif
if (sockfd_server_send > -1)
goto end_file_socket_create;
sockfd_server_send = socket(AF_LOCAL, SOCK_STREAM, 0);
...
sockfd_server_recv = socket(AF_LOCAL, SOCK_STREAM, 0);
...
sockfd_server_recv_passive = socket(AF_LOCAL, SOCK_STREAM, 0);
...
sockfd_server_rule = socket(AF_LOCAL, SOCK_STREAM, 0);
...
memset(&server_addr_send, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_send.sun_path, UNIX_PATH_MAX, THERMAL_SEND_CLIENT_SOCKET);
server_addr_send.sun_family = AF_LOCAL;
memset(&server_addr_recv, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_recv.sun_path, UNIX_PATH_MAX, THERMAL_RECV_CLIENT_SOCKET);
server_addr_recv.sun_family = AF_LOCAL;
memset(&server_addr_recv_passive, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_recv_passive.sun_path, UNIX_PATH_MAX, THERMAL_RECV_PASSIVE_CLIENT_SOCKET);
server_addr_recv_passive.sun_family = AF_LOCAL;
memset(&server_addr_rule, 0, sizeof(struct sockaddr_un));
snprintf(server_addr_rule.sun_path, UNIX_PATH_MAX, THERMAL_SEND_RULE_SOCKET);
server_addr_rule.sun_family = AF_LOCAL;
/* Delete existing socket file if necessary */
unlink(server_addr_send.sun_path);
unlink(server_addr_recv.sun_path);
unlink(server_addr_recv_passive.sun_path);
unlink(server_addr_rule.sun_path);
rc = bind(sockfd_server_send,(struct sockaddr const *)&server_addr_send, sizeof(struct sockaddr_un));
...
rc = bind(sockfd_server_recv,(struct sockaddr const *)&server_addr_recv, sizeof(struct sockaddr_un));
...
rc = bind(sockfd_server_recv_passive,(struct sockaddr const *)&server_addr_recv_passive, sizeof(struct sockaddr_un));
if (rc != 0) {
msg("Thermal-Server: Recv passive socket: bind error - %s", strerror(errno));
goto error;
}
rc = bind(sockfd_server_rule,(struct sockaddr const *)&server_addr_rule, sizeof(struct sockaddr_un));
...
/* Allow any client to connect to send socket.
Allow any client to connect to passive receive socket.
Only root group clients can connect recieve socket. */
chmod(server_addr_send.sun_path, 0666);
chmod(server_addr_recv.sun_path, 0660);
chmod(server_addr_recv_passive.sun_path, 0666);
chmod(server_addr_rule.sun_path, 0666);
end_file_socket_create:
sockfd_server_log = socket(AF_LOCAL, SOCK_STREAM, 0);
if (sockfd_server_log < 0)
goto error;
memset(&server_log, 0, sizeof(struct sockaddr_un));
snprintf(server_log.sun_path, UNIX_PATH_MAX, " %s",
UI_LOCALSOCKET_NAME);
server_log.sun_family = AF_LOCAL;
/* abstract namespace socket starts with NULL char */
server_log.sun_path[0] = '\0';
rc = bind(sockfd_server_log,
(struct sockaddr const *)&server_log,
(int)(sizeof(sa_family_t) + 1
+ strlen(UI_LOCALSOCKET_NAME)));
...
rc = listen(sockfd_server_send, NUM_LISTEN_QUEUE);
...
rc = listen(sockfd_server_recv, NUM_LISTEN_QUEUE);
...
rc = listen(sockfd_server_recv_passive, NUM_LISTEN_QUEUE);
...
rc = listen(sockfd_server_log, NUM_LISTEN_QUEUE);
...
rc = listen(sockfd_server_rule, NUM_LISTEN_QUEUE);
...
rc = pthread_create(&listen_client_fd_thread, NULL, do_listen_client_fd, NULL);
......
ret = 0;
return ret;
error:
......
return ret;
}
2. 各个socket监听
do_listen_client_fd函数,这里我们主要讲一下两个socket一个是sockfd_server_send这个主要是client用来注册回调,另一个是sockfd_server_recv时client给thermal-engine发送消息的。我们先分析这个函数,后面我们再从client端进行分析。
static void *do_listen_client_fd(void *data)
{
int fd;
uint8_t i;
int nread;
int result;
socklen_t client_len;
int client_fd = -1;
struct sockaddr_un client_addr;
fd_set t_readfds,testfds;
FD_ZERO(&t_readfds);
FD_SET(sockfd_server_send, &t_readfds);
FD_SET(sockfd_server_recv, &t_readfds);
FD_SET(sockfd_server_recv_passive, &t_readfds);
FD_SET(sockfd_server_log, &t_readfds);
FD_SET(sockfd_server_rule, &t_readfds);
for (i = 0; i < NUM_LISTEN_QUEUE; i++) {
thermal_send_fds[i] = -1;
}
while(server_socket_exit != 1) {
testfds = t_readfds;
result = select(FD_SETSIZE, &testfds, (fd_set *)0,//使用select
(fd_set *)0, (struct timeval *) 0);
if (result < 1) {
msg("Thermal-Server: %s select error", __func__);
break;
}
for (fd = 0; fd < FD_SETSIZE; fd++) {
if (FD_ISSET(fd,&testfds)) {
if (fd == sockfd_server_send) {
client_len = sizeof(struct sockaddr_un);
client_fd = accept(sockfd_server_send,//client的fd
(struct sockaddr *)&client_addr,
&client_len);
if (client_fd < 0)
continue;
FD_SET(client_fd, &t_readfds);//将client的fd放入select
info("Thermal-Server: Adding thermal event listener on fd %d\n", client_fd);
for (i = 0; i < NUM_LISTEN_QUEUE && thermal_send_fds[i] != -1; i++)
continue;
if (i < NUM_LISTEN_QUEUE)
thermal_send_fds[i] = client_fd;//将client的fd放入thermal_send_fds数组中
notify_client_on_register(client_fd);//client注册回调
} else if (fd == sockfd_server_recv ||
fd == sockfd_server_recv_passive) {
client_len = sizeof(struct sockaddr_un);
client_fd = accept(fd,
(struct sockaddr *)&client_addr,
&client_len);
if (client_fd < 0)
continue;
thermal_recv_data_from_client(client_fd, fd);//从client收消息
close(client_fd);
} else if (fd == sockfd_server_log || fd == sockfd_server_rule) {
client_len = sizeof(struct sockaddr_un);
client_fd = accept(fd,
(struct sockaddr *)&client_addr,