The Unix domain stream socket code is provided here. As always, let us look at how the connection establishment and data transfer occurs in an Unix Stream socket connection
As referenced in Wikipedia , the unix socket references the file system of the local host system and processes view the socket as file system inodes.
In the example provided previously, the server code opens a socket and later binds with the socket file present in /tmp folder as /tmp/unix_socket.sock. The remove API used will remove any previous instance of the socket that was opened. Code snippets from the example are provided below.
const char *path= “/tmp/unix_socket.sock”;
/* Part 1 – create the socket */
sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
remove(path);
/* copy the path to the relevant sockaddr structure and perform bind*/
snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
bind(sockserver, (struct sockaddr *)servaddr, sizeof(struct sockaddr_un));
After Bind is completed, the server side code will invoke the listen API to convert itself to a passive socket and wait for incoming connections using the accept API call which is a blocking call.
listen(sockserver, 1);
sockclient = accept(sockserver, (struct sockaddr *)cliaddr, &length);
The output of the “ss -x -a shell command” provides the server socket connection state at the instance it is awaiting a connection to a client
NetidState Recv-Q Send-Q Local Address:Port Peer Address:Port
u_strLISTEN 0 1 /tmp/unix_socket.sock 27306 * 0
As can be seen from the output above, the state of the Unix server is in Listen mode. Another unique thing that can be seen is that the operating system has provided a port number for the socket which is 27306 in this present instance. The peer address is still not connected.
The client on its end opens a socket using the socket API and then attempts to connect to the server socket using the connect API. The code snippets are shown below
/* Part 1 – create the socket */
sockserver = socket(AF_UNIX, SOCK_STREAM, 0);
snprintf(servaddr->sun_path, (strlen(path)+1), “%s”, path);
connect(sockserver, (struct sockaddr *)servaddr, sizeof(struct sockaddr_un))
After the successful invocation of the connect API, the server code will accept the incoming client connection and the server now moves to connection established state. The output of the “ss -x shell command” indicates the same.
NetidState Recv-Q Send-Q Local Address:Port Peer Address:Port
u_strESTAB 0 1 /tmp/unix_socket.sock 27424 * 27425
The Peer side now has a port assigned to it by the operating system. Data transaction between both ports can now happen via send and recv APIs
Pingback: Unix Domain Stream Socket Example | Hitch Hiker's Guide to Learning
Pingback: Sequenced Socket Packet code example | Hitch Hiker's Guide to Learning