[Kernel Version]
linux-2.6.31
[Remaining defects]
1. Calls to certain parameters of getsockopt and setsockopt (*sockop functions defined in net/unix/af_unix.c retain interfaces and return Eopnotsupp errors);
2, the SS command to see the local socket status needs to be further confirmed;
[Precautions]
1. When using a local socket for communication, the communication process does not switch state machine through the message interaction:
A) server side after executing the listen function, the socket is in the listening state;
b) Client side when the Connect function is executed, the kernel normally sets the sock state to ss_connected and the SK state to tcp_established. Then notifies the server that there is a client request (sending a Sigio signal to the server's socket);
c) Once a situation results in a maximum link request on the server side (which should be defined by the Sk_max_ack_backlog member, as specified in the Listen function), the client should time out in 2,147,483,647 seconds if the connection time-out is not set
Include/linux/kernel.h
#define Long_max((LONG) (~0ul>>1))
Include/linux/sched.h
#definemax_schedule_timeoutLong_max
Net/core/sock.c
void Sock_init_data (struct socket *sock, struct sock *sk)
{
...
Sk->sk_sndtimeo=max_schedule_timeout;
...
}
2, the local socket and network socket communication mechanism is somewhat different (for example, the TCP state machine is not implemented through the message interaction, getsockopt can not take the TCP connection state, the kernel in the processing of local sockets, there may not be some protocol stack process, That is, the integrity check of the message may be ignored, and the functions used on many network sockets need to be considered as appropriate when migrating to a local socket.
[Server-side code]
Int ct_ipc_sock_create (Struct ct_fd * sockfd, int server_flag) {log_debug ("server _flag: %d ", server_flag);int ret = ct_ret_success;int result = 0; Struct sockaddr_un srv_addr;memset (&srv_addr, 0, sizeof (Struct sockaddr_un)); (Server_socket == server_flag) {Sockfd->fd = socket (Pf_unix, sock_dgram, 0);if (0&NBSP;>&NBSP;SOCKFD->FD) {log_err ("Create unix socket error");ret = ct_ret_sys_sock_create_err;goto ct_ipc_sock_create_err;} srv_addr.sun_family=af_unix; strncpy (srv_addr.sun_path, unix_domain, sizeof (Srv_addr.sun_path)- 1); unlink (Unix_domain); Ret=bind (SOCKFD->FD, (struct sockaddr*) &srv_addr, sizeof (SRV_ADDR)); if (ret==-1) {Log_err ("cannot bind server socket ( %d) ", &NBSP;SOCKFD->FD); ret = ct_ret_sys_sock_bind_err;goto ct_ipc_sock_bind_listen_err;}} else if (Client_socket == server_flag) {Sockfd->fd = socket (PF_UNIX, SOCK _stream, 0);if (0&NBSP;>&NBSP;SOCKFD->FD) {log_err ("Create unix socket error"); Ret = ct_ret_sys_sock_create_err;goto ct_ipc_sock_create_err;} Log_debug ("sockfd: %d", &NBSP;SOCKFD->FD); setsockopt (Sockfd->fd, sol_socket, tcp_nodelay, &result, sizeof (int)); srv_addr.sun_family=af_unix; strncpy (srv_addr.sun_path, unix_ Domain_cloud, sizeof (Srv_addr.sun_path)-1); unlink (Unix_domain_cloud); Ret=bind ( SOCKFD->FD, (struct sockaddr*) &srv_addr,sizeof (SRV_ADDR)), if (ret==-1) {Log_err ("Cannot bind server socket (%d) ", &NBSP;SOCKFD->FD); ret = ct_ret_sys_sock_bind_err;goto ct_ipc_sock_bind_listen_err;} LOg_debug ("%s", strerror (errno)); Ret=listen (Sockfd->fd, max_listen_backlog); if ( Ret==-1) { log_err ("cannot listen the client connect request (%d) ", &NBSP;SOCKFD); ret = ct_ret_sys_sock_listen_err; goto ct_ Ipc_sock_bind_listen_err;}} Else{}log_debug ("%s", strerror (errno)); Return ret;ct_ipc_sock_bind_listen_err:close (SOCKFD->FD); Ct_ipc_sock_create_err:sockfd->fd = -1;return ret;} Int ct_select_run () {int ret = ct_ret_success;fd_set rset, allset;int Nfds = 0;int maxfd = 0;int cloudfd = 0;int read_num = 0 ; int write_num = 0;socklen_t addrlen;struct sockaddr_in addr;char rsp[] = "ACK"; Char data_buf[max_buf] = {0};log_debug ("sockfd: %d, nlfd.fd: %d, cloud_sockfd.fd: %d ", &NBSP;IPC_SOCKFD.FD,&NBSP;NLFD.FD,&NBSP;CLOUD_SOCKFD.FD); Group_filter_init (); maxfd = ipc_sockfd.fd ; Fd_zero (&allset); Fd_set (Cloud_sockfd.fd, &allset); Log_debug ("Sockfd: %d, maxfd: %d, cloud_ sockfd.fd: %d ", &NBSP;IPC_SOCKFD.FD,&NBSP;MAXFD,&NBSP;CLOUD_SOCKFD.FD);while (1/*nfds == 0* /) {Rset = allset;log_debug ("sockfd: %d", &NBSP;IPC_SOCKFD.FD); Nfds = select (maxfd + 1, &rset, null, null, null);if (0 > nfds) {Log_err (" select error: %s ", strerror (errno)); Ret = ct_ret_sys_sock_select_err;return ret;} if (Fd_isset (Cloud_sockfd.fd, &rset)) {log_debug ("cloud_sockfd: %d", cloud_ SOCKFD.FD); Cloudfd = accept (cloud_sockfd.fd, (struct sockaddr *) &addr, & Addrlen);if (cloudfd < 0) { &nBsp; log_err ("accept (%d) client error: %d", &NBSP;CLOUD_SOCKFD.FD, ret); Continue;} Read_num = read (CLOUDFD,&NBSP;DATA_BUF,&NBSP;MAX_BUF); Log_debug ("client socket is: %d , read_num: %d ", cloudfd, read_num); if (read_num > 0) {write_num = write (cloudfd, sta_info , (sizeof (STA_LIST_ATTR) *num + sizeof (int)); Log_debug ("client socket is: %d, write_num: %d ", cloudfd, write_num);;} }close (CLOUDFD);}} Return ret;}
[Client-side code]
Int do_filter_notify (Cloud_cmd_attr * attr, char * buf, int buf_len) { Int ret = 0;int client_fd = -1;char recv_buf[128] = {0};struct sockaddr_un srv_addr;int maxfd = 0;int nfds = 0;fd_set rset, allset;struct timeval tv;struct timeval t;/* wait up to Five seconds. */tv.tv_sec = cli_time_out;tv.tv_usec = 0;memset (&SRV_ADDR, 0, sizeof (Struct sockaddr_un)); Client_fd = socket (af_unix, sock_stream, 0) ; Log_debug ("client_fd: %d\n", &NBSP;CLIENT_FD);p rintf ("client_fd: %d\n", &NBSP;CLIENT_FD);if (-1 &NBSP;!=&NBSP;CLIENT_FD) {t.tv_sec = unix_sock_connect_timeo;t.tv_usec = 0; ret = setsockopt (client_fd, sol_socket, so_sndtimeo, &t, sizeof (t)); srv_ Addr.sun_family = af_unix;memcpy (Srv_addr.sun_path, unix_domain_cloud, strlen (Unix_domain_cloud)); Log_debug ("Srv_addr.sun_ Path: %s\n ", srv_addr.sun_path);p rintf (" srv_addr.sun_path: %s\n ", srv_addr.sun_path); ret = connect (client_fd, (struct sockaddr *) &srv_addr, sizeof (SRV_ADDR)); ( -1 == ret) {log_err ("error: %d, %s\n", errno, strerror (errno)); ret = &NBSP;CT_RET_SYS_SOCK_CONNECT_ERR;GOTO&NBSP;CLOSE_FD;} Else {int write_num = 0;write_num = write (Client_fd, attr, sizeof ( cloud_cmd_attr);if (sizeof (cloud_cmd_attr) == write_num) {fd_zero (&allset); Fd_set (Client_fd, &allset);maxfd = client_fd;rset = allset;nfds = Select (MAXFD&NBSP;+&NBSP;1,&NBSP;&RSET,&NBSP;NULL,&NBSP;NULL,&NBSP;&TV); Log_debug ("nfds: %d\n", nfds);p rintf ("nfds: %d\n", nfds);if (Fd_isset (Client_fd, &rset)){int num = 0;if (null == buf) {Num = read (Client_fd, recv_buf, sizeof (RECV_BUF));} Else{num = read (Client_fd, buf, buf_len);} if (num <= 0) {log_err ("Read %d error", client_fd); ret = CT_ Ret_fd_read_err;} Else{log_debug ("client_fd: %d, read length: %d", client_fd, num);p rintf ("Client_ fd: %d, read length: %d ", client_fd, num);if (NULL == buf) {Log_ Debug ("recv_buf: %s\n", recv_buf);if (!strcasecmp (recv_buf, "ack")) {Ret = ct_ret _success;}} ELSE{//&NBSP;DO&NBSP;NOTHING}}GOTO&NBSP;CLOSE_FD;} Else{log_err ("no response from: %d", &NBSP;CLIENT_FD);p rintf ("no response from: % D ", client_fd); ret = ct_ret_sock_select_timeout;goto close_fd;}} Else{log_err ("(%d) write to peer %s error (num: %d)", clienT_fd, unix_domain_cloud, ret);p rintf ("(%d) write to peer %s error (num : %d) ", client_fd, unix_domain_cloud, ret);ret = ct_ret_fd_write_err;goto CLOSE_FD;}}} else{log_err ("Create unix socket error");p rintf ("Create unix socket error") ); ret = ct_ret_sys_sock_create_err;} Return ret;close_fd:close (CLIENT_FD); client_fd = -1;return ret;}
Linux interprocess communication-local socket (TCP part)