- What Is Socket In Linux?
- Use Cases
- Socket Types
- Stream Socket
- Datagram Socket
- Raw Socket
- Sequenced Packet Socket
- Java Socket
- Python Socket
- How Linux creates sockets and counts them
- A deep dive into what goes under the hood in the Linux kernel when you can the socket system call
- What are these sockets about?
- Where to look for the list of sockets in my system?
- What happens under the hood when the socket syscall gets called?
- Sockets and resource limits
- Counting the number of sockets in the system
- What about namespaces?
- Closing thoughts
- Resources
- Recommended articles
- Stay in touch!
- Understanding Sockets
- Introduction
- Prerequisites
- What is a Stream Socket?
- Creating TCP-based Stream Sockets
- Examining TCP-Based Stream Sockets
- Connecting to TCP-Based Stream Sockets
- What is a Datagram Socket?
- Creating Datagram Sockets
- Examining Datagram Sockets
- Testing Datagram Sockets
- What is a Unix Domain Socket?
- Creating Unix Domain Sockets
- Examining Unix Domain Sockets
- Testing Unix Domain Sockets
- Conclusion
What Is Socket In Linux?
The socket is a mechanism that provides a connection between the two-processor system by using network stacks. In a more clear way, we can use sockets to communicate and transfer data between two systems. As we know Unix and Linux systems work on file logic. Everything in the operating system is a file where network connections are files too.
Use Cases
Sockets can be used in different cases.
- We can use socket to transfer data between two different process in same system.
- Send command to the remote system
- Download data from remote system
Socket Types
There are four main socket types. Stream sockets and Datagram sockets are popular types.
Stream Socket
Stream sockets uses TCP protocol for transmission. So this makes stream socket reliable way for transmission. If there is a network related problem we will get error messages about it. If we send X, Y, Z data the remote will get them in the same order X, Y, Z.
Datagram Socket
Datagram sockets uses UDP which makes the data delivery inconsistent. Another feature of datagram socket is connection-less. The sender just send data and can not be sure whether it is arrived to the destination.
Raw Socket
As its name suggest Raw sockets do not provide ready to use protocol. It is mainly used for creating new protocol where both side can understand. Raw sockets do not used regularly.
Sequenced Packet Socket
Sequenced Packet Socket is similar to the Stream Socket but have record boundaries. Sequnced Packet Socket is not popular way to use socket.
Java Socket
Java programming language provides socket support.As we can see we need to use IP address and Port number in order to create a socket. Socket related function can be found in java.net.Socket name space The communication diagram is like below.
Python Socket
Python programming language also provides Socket related libraries. We can import the Socket library with the following code. Python also supports encryption of socket communication.
Источник
How Linux creates sockets and counts them
A deep dive into what goes under the hood in the Linux kernel when you can the socket system call
by Ciro S. Costa — Oct 16, 2018
If you’ve been working with web servers for a little while, you certainly have already hit the classic “address already in use” (EADDRINUSE).
Here in this article, we go through not only how to see whether such condition as conditioned to happen (by looking at the list of open sockets), but also verify in the actual Kernel code paths where that check happens.
In case you’ve been wondering about how the socket(2) syscall works where are these sockets stored, make sure you stick to the end!
This is the sixth article in a series of 30 articles around procfs: A Month of /proc.
If you’d like to keep up to date with it, make sure you join the mailing list!
What are these sockets about?
Sockets are the constructs that allow processes on different machines to communicate through an underlying network, being also possibly used as a way of communicating with other processes in the same host (through Unix sockets).
The analogy that really stuck with me is the one presented in the book Computer Networking: A top-down approach.
At a very high-level, we can think of the server machine as this “house” with a set of doors.
With each door corresponding to a socket, the client can arrive at the door of the house and “knock” at it.
Right after knocking (sending the SYN packet), the house then automatically responds back with a response ( SYN+ACK ), which is then acknowledged by the house (yep, smart house with a “smart door”).
Meanwhile, while the process just sits there within the house, the clients get organized by the “smart house”, which creates two lines: one for those that the house is still greeting, and another one for those that it finished greeting.
Whenever new clients land in the second line, the process can then let it come in.
Once this connection gets accepted (the client is told to come in), the server is then able to communicate with it, transmitting and receiving data at wish.
One detail to note is that the client doesn’t really “get in” — the server creates a “private door” in the house (a client socket) and then communicates with the client from there.
If you’d like to follow the step by step of implementing a TCP server in C, make sure you check this article! Implementing a TCP server.
Where to look for the list of sockets in my system?
Having the mental model of how the TCP connection establishment looks like, we can now “get into the house” and explore how the machine is creating these “doors” (the sockets), how many doors our house has and in which state they are (are they closed? are they opened?).
For doing so, let’s consider the example of a server that just creates a socket (the door!) and does nothing with it.
Under the hood, such simple syscall ends up triggering a whole bunch of internal methods (more on that in the next session) that at some point allows us to seek for information about active sockets under three different files: /proc/
While the fd directory presents us a list of files opened by the process, /proc/
/net/tcp file gives us information regarding currently active TCP connections (in their various states) under the process network namespace. sockstat , on the other hand, acts more like a summary.
Starting with the fd directory, we can see that after the socket(2) call we can see the socket file descriptor in the list of file descriptors:
Given that from a simple call to socket(2) we don’t have a TCP connection, there’s no relevant information to be gathered from /proc/
From the summary ( sockstat ), we can guess that we’re increasing the number of allocated TCP sockets:
To make sure that we’re really increasing the alloc number, we can modify the source code above and allocate 100 sockets instead:
Now, checking that again, we can see the alloc at a higher number:
Now, the question is — how does the socket gets created under the hood?
What happens under the hood when the socket syscall gets called?
socket(2) is pretty much a factory that produces the underlying structures for handling operations on such socket.
Making use of iovisor/bcc , we can trace the deepest invocation that happens in the sys_socket call stack and from there understand each step.
Starting from sys_socket itself, this syscall wrapper is the first thing to be touched at kernelspace, being responsible for performing various checks and preparing some flags to pass down to subsequent invocations.
Once preliminary validations have been performed, it allocates in its stack a pointer to a struct socket , the struct that will end up holding the non-protocol specific information about the socket:
Given that at the moment that we create the socket we can choose between different types and protocol families (like, UDP, UNIX, and TCP), the struct socket contains an interface ( struct proto_ops* ) that defines the basic constructs that sockets implement (regardless of their families/type), which gets initiated on the next method called: sock_create .
Continuing with our deep dive, we can now look closely at how the actual struct socket gets allocated by sock_alloc() .
What that method does is allocate two things: a new inode , and a socket object.
These two are bound together via the sockfs filesystem, which is then responsible for not only keeping track of socket information in the system, but also providing the translation layer between regular filesystem calls (like write(2) ) and the network stack (regardless of the underlying communication domain).
By tracing sock_alloc_inode , the method responsible for allocating the inode in sockfs , we’re able to see how that gets set up:
Sockets and resource limits
Given that a filesystem inode can be referred from the userspace from a file descriptor, after we have the underlying Kernel structs all set up, sys_socket is then responsible for generating a file descriptor for the user (going through the resource limits validations as presented in Process resource limits under the hood.
If you’ve wondered why it is the case that you might receive a “too many open files” error for socket(2) , that’s the reason — it goes through the same resource limits checks:
Counting the number of sockets in the system
If you’ve paid attention to the sock_alloc call, there was a part of it that took care of increasing the number of sockets that are “in-use”.
Being this_cpu_add a macro, we can look at its definition and understand a bit more about it:
Now, given that we’re always adding to sockets_in_use , we can at least guess that if we go through the method that is registered for /proc/net/sockstat is going to use that value, which it really does (with also performing an addition over the values registered for each CPU):
What about namespaces?
As you might’ve noticed, there’s no logic in the code related to namespaces when it comes to counting how many sockets where allocated.
That’s something that at first really surprised me given that I thought the networking stack was something that was the most namespaced, but it turns out that there are still some points that are not.
/net/tcp` is namespaced, but `/proc/
/net/sockstat` is not (it still isn’t, the patch wasn’t accept) pic.twitter.com/BcaVCAOczY
If you’d like to see that by yourself, make sure you follow the article Using network namespaces and a virtual switch to isolate servers.
The gist of it is that you can create a bunch of sockets, see sockstat , then create a network namespace, get into it, and then see that although you can’t see the TCP sockets from the whole system over there (namespaces in action!), you can see the total number of allocated sockets in the system (not namespaced).
Closing thoughts
It’s interesting to see how after exploring the inner workings of the Kernel by just being curious about /proc is leading to answers to why some specific behaviors that I’ve seen in daily operations work in such way.
Given that this is just the first article that is about /proc/net and I’ve already learned a lot, I can’t wait to start digging deeper into the rest of it!
If you’d like to follow along with me, make sure you subscribe to the mailing list.
In case you have any questions or thoughts you’d like to share, please let me know!
I’m cirowrc on Twitter, and I’d love to chat with you!
Have a good one, Ciro
Resources
Recommended articles
If you’ve gotten some knowledge from this article, these are some others that you might take advatange of as well!
Stay in touch!
From time to time I’ll deliver some content to you.
The emails are not automatic — it’s all about things I thought were worth sharing that I’d personally like to receive.
If you’re into Twitter, reach me at @cirowrc.
Источник
Understanding Sockets
Published on March 3, 2021
Introduction
Sockets are a way to enable inter-process communication between programs running on a server, or between programs running on separate servers. Communication between servers relies on network sockets, which use the Internet Protocol (IP) to encapsulate and handle sending and receiving data.
Network sockets on both clients and servers are referred to by their socket address. An address is a unique combination of a transport protocol like the Transmission Control Protocol (TCP) or User Datagram Protocol (UDP), an IP address, and a port number.
In this tutorial you will learn about the following different types of sockets that are used for inter-process communication:
- Stream sockets, which use TCP as their underlying transport protocol
- Datagram sockets, which use UDP as their underlying transport protocol
- Unix Domain Sockets, which use local files to send and receive data instead of network interfaces and IP packets.
In each section of this tutorial you will also learn how to enumerate the respective socket types on a Linux system. You’ll examine each type of socket using a variety of command line tools.
Prerequisites
The examples in this tutorial were validated on an Ubuntu 20.04 server. You can follow this tutorial using most modern Linux distributions on a local computer or remote server, as long as you have the equivalent version of each of the required tools for your distribution installed.
To get started using Ubuntu 20.04, you will need one server that has been configured by following our Initial Server Setup for Ubuntu 20.04 guide.
You will also need a few other packages in order to examine sockets on your system. Ensure that your local package cache is up to date using the apt update command:
Then install the required packages using this command:
The iproute2 package contains the ss utility, which is what we’ll use to inspect sockets. We’ll use the netcat-openbsd package to install netcat. Note that netcat is abbreviated to nc when it is invoked on the command line. Finally, we’ll use the socat package to create example sockets.
What is a Stream Socket?
Stream sockets are connection oriented, which means that packets sent to and received from a network socket are delivered by the host operating system in order for processing by an application. Network based stream sockets typically use the Transmission Control Protocol (TCP) to encapsulate and transmit data over a network interface.
TCP is designed to be a reliable network protocol that relies on a stateful connection. Data that is sent by a program using a TCP-based stream socket will be successfully received by a remote system (assuming there are no routing, firewall, or other connectivity issues). TCP packets can arrive on a physical network interface in any order. In the event that packets arrive out of order, the network adapter and host operating system will ensure that they are reassembled in the correct sequence for processing by an application.
A typical use for a TCP-based stream socket would be for a web server like Apache or Nginx handling HTTP requests on port 80 , or HTTPS on port 443 . For HTTP, a socket address would be similar to 203.0.113.1:80 , and for HTTPS it would be something like 203.0.113.1:443 .
Creating TCP-based Stream Sockets
In the following example you’ll use the socat (short for SO cket CAT ) command to emulate a web server listening for HTTP requests on port 8080 (the alternative HTTP port). Then you’ll examine the socket using the ss , and nc commands.
First, run the following socat commands to create two TCP-based sockets that are listening for connections on port 8080 , using IPv4 and IPv6 interfaces:
- The TCP4-LISTEN:8080 and TCP6-LISTEN:8080 arguments are the protocol type and port number to use. They tell socat to create TCP sockets on port 8080 on all IPv4 and IPv6 interfaces, and to listen to each socket for incoming connections. socat can listen on any available port on a system, so any port from 0 to 65535 is a valid parameter for the socket option.
- The fork option is used to ensure that socat continues to run after it handles a connection, otherwise it would exit automatically.
- The /dev/null path is used in place of a remote socket address. In this case it tells socat to print any incoming input to the /dev/null file, which discards it silently.
- The ipv6only=1 flag is used for the IPv6 socket to tell the operating system that the socket is not configured to send packets to IPv4-mapped IPv6 addresses. Without this flag, socat will bind to both IPv4 and IPv6 addresses.
- The & character instructs the shell to run the command in the background. This flag will ensure that socat continues to run while you invoke other commands to examine the socket.
You will receive output like the following, which indicates the two socat process IDs that are running in the background of your shell session. Your process IDs will be different than the ones highlighted here:
Now that you have two socat processes listening on TCP port 8080 in the background, you can examine the sockets using the ss and nc utilities.
Examining TCP-Based Stream Sockets
To examine TCP sockets on a modern Linux system using the ss command, run it with the following flags to restrict the output:
- The -4 and -6 flags tell ss to only examine IPv4 or IPv6 sockets respectively. Omitting this option will display both sets of sockets.
- The t flag limits the output to TCP sockets. By default the ss tool will display all types of sockets in use on a Linux system.
- The l flag limits the output to listening sockets. Without this flag, all TCP connections would be displayed, which would include things like SSH, clients that may be connected to a web-server, or connections that your system may have to other servers.
- The n flag ensures that port numbers are displayed instead of service names.
First run the ss -4 -tln command to examine the IPv4 TCP-based sockets that are listening for connections on your system:
You will receive output like the following:
There may be other lines with other ports in your output depending on which services are running on your system. The highlighted 0.0.0.0:8080 portion of the output indicates the IPv4 TCP socket is listening on all available IPv4 interfaces on port 8080 . A service that is only listening on a specific IPv4 address will show only that IP in the highlighted field, for example 203.0.113.1:8080 .
Now run the same ss command again but with the -6 flag:
You will receive output like the following:
There may be other lines with other ports in your output depending on which services are running on your system. The highlighted [::]:8080 portion of the output indicates the IPv6 TCP socket is listening on all available IPv6 interfaces on port 8080 (as indicated by the :: characters, which are IPv6 notation for an address composed of all zeros). A service that is only listening on a specific IPv6 address will show only that IP in the highlighted field, for example [2604:a880:400:d1::3d3:6001]:8080 .
Connecting to TCP-Based Stream Sockets
So far you have learned how to create and enumerate TCP sockets on both IPv4 and IPv6 interfaces. Now that you have two sockets listening for connections, you can experiment with connecting to sockets using the netcat utility.
Using netcat to test TCP connections to local and remote sockets is a very useful troubleshooting technique that can help isolate connectivity and firewall issues between systems.
To connect to the IPv4 socket over the local loopback address using netcat, run the following command:
- The -4 flag tells netcat to use IPv4.
- The -v flag is used to print verbose output to your terminal.
- The — z option ensures that netcat only connects to a socket, without sending any data.
- The local loopback 127.0.0.1 IP address is used since your system will have its own unique IP address. If you know the IP for your system you can test using that as well. For example, if your system’s public or private IP address is 203.0.113.1 you could use that in place of the loopback IP.
You will receive output like the following:
The highlighted line is the output from netcat. It indicates that netcat connected to the TCP socket listening on the loopback 127.0.0.1 IPv4 address on port 8080 . You can ignore the second line, it is from the socat process running in the background in your terminal.
Now you can repeat the same connection test but using IPv6. Run the following netcat command:
You should receive output like the following:
The highlighted line is the output from netcat. It indicates that netcat connected to the TCP socket listening on the loopback ::1 IPv6 address on port 8080 . Again, you can ignore the second line of output.
To clean up your sockets, you’ll need to run the fg (foreground) command for each socat process that you created. Then you’ll use CTRL+C to close each socat. fg will bring processes to the foreground of your terminal in the reverse order that you ran them, so when you run it, the second socat instance will be the one that you interact with first.
Run fg to bring the second IPv6 socat instance to the foreground of your terminal. Then run CTRL+C to close it.
You will receive output like the following:
Press CTRL+C to stop the process.
Now run fg again to clean up the first IPv4 socket. You should have output like the following:
Press CTRL+C to stop the process.
You have now created, examined, and connected to IPv4 and IPv6 sockets on your system. These techniques and tools will work on local development systems, or remote production servers, so try experimenting with each tool to become more familiar with how they can be used to test and troubleshoot TCP sockets.
What is a Datagram Socket?
Datagram sockets are connectionless, which means that packets sent and received from a socket are processed individually by applications. Network-based datagram sockets typically use the User Datagram Protocol (UDP) to encapsulate and transmit data.
UDP does not encode sequence information in packet headers, and there is no error correction built into the protocol. Programs that use datagram-based network sockets must build in their own error handling and data ordering logic to ensure successful data transmission.
UDP sockets are commonly used by Domain Name System (DNS) servers. By default, DNS servers use port 53 to send and receive queries for domain names. An example UDP socket address for a DNS server would be similar to 203.0.113.1:53 .
Note: Although the protocol is not included in the human-readable version of the socket address, operating systems differentiate socket addresses by including TCP and UDP protocols as part of the address. So a human-readable socket address like 203.0.113.1:53 could be using either protocol. Tools like ss , and the older netstat utility, are used to determine which kind of socket is being used.
The Network Time Protocol (NTP) uses a UDP socket on port 123 to synchronize clocks between computers. An example UDP socket for the NTP protocol would be 203.0.113.1:123 .
Creating Datagram Sockets
As in the previous TCP socket example, in this section you’ll use socat again to emulate an NTP server listening for requests on UDP port 123 . Then you’ll examine the sockets that you create using the ss and nc commands.
First, run the following socat commands to create two UDP sockets that are listening for connections on port 123, using IPv4 and IPv6 interfaces:
You will receive output like the following, which indicates the two socat process IDs that are running in the background of your shell session. Your process IDs will be different than the ones highlighted here:
- Each command is prefixed with sudo , because ports 0 to 1024 are reserved on most systems. sudo runs a command with administrator permissions, which allows socat to bind to any port in the reserved range.
- The UDP4-LISTEN:123 and UDP6-LISTEN:123 arguments are the protocol type and port to use. They tell socat to create UDP based sockets on port 123 on both IPv4 and IPv6 interfaces, and to listen for incoming data. Again any port in the entire range of 0-65535 is a valid parameter for UDP sockets.
- The fork , ipv6only=1 , and /dev/null arguments are used in the same manner as described in the previous TCP example.
Now that you have two socat processes listening on UDP port 123 , you can examine the sockets using the ss and nc utilities.
Examining Datagram Sockets
To examine UDP sockets on a modern Linux system using the ss command, run it with the following -4 , -6 , and uln` flags to restrict the output:
The u flag limits the output to UDP sockets.
The other flags are the same as the ones used in the previous TCP example.
First run the ss -4 -uln command to examine the IPv4 UDP sockets that are listening for connections on your system:
You will receive output like the following:
There may be other lines with other ports in your output depending on which services are running on your system. The highlighted 0.0.0.0:123 portion of the output indicates the IPv4 UDP socket is available on all IPv4 interfaces on port 123 . A service that is only available on a specific IPv4 address will show only that IP in the highlighted field, for example 203.0.113.1:123 .
Now run the same ss command again but with the -6 flag:
You will receive output like the following:
There may be other lines with other ports in your output depending on which services are running on your system. The highlighted [::]:123 portion of the output indicates the IPv6 TCP socket is available on all IPv6 interfaces on port 123 (as indicated by the :: characters). A service that is only available on a specific IPv6 address will show only that IP in the highlighted field, for example [2604:a880:400:d1::3d3:6001]:123 .
Testing Datagram Sockets
Now that you are familiar with how to create and enumerate UDP sockets on both IPv4 and IPv6 interfaces, you can experiment with connecting to them. As with TCP sockets, you can experiment with UDP sockets using the netcat utility.
To connect to the example UDP socket on port 123 that you created in the previous section of this tutorial, run the following netcat command:
- The -4 flag tells netcat to use IPv4.
- The -u option instructs netcat to use UDP instead of TCP.
- The -v flag is used to print verbose output to your terminal.
- The — z option ensures that netcat only connects to a socket, without sending any data.
- The local loopback 127.0.0.1 IP address is used since your system will have its own unique IP address. If you know the IP for your system you can test using that as well. For example, if your system’s public or private IP address is 203.0.113.1 you could use that in place of the loopback IP.
You will receive output like the following:
The output indicates that netcat did not receive an error from the UDP socket listening on the loopback 127.0.0.1 IPv4 address on port 123 . This lack of an error response is used to infer that the socket at 127.0.0.1:123 is available. This behaviour is different from TCP sockets, which need to exchange packets to confirm if a socket is available.
Note: If the socket in this example was unavailable, the remote system would return an ICMP type 3 message (Destination Unreachable) with a Code of 3, indicating that the port is unreachable on the remote host.
Inferring that a socket is available based on a lack of error response assumes that there are no firewalls or connectivity issues that are blocking ICMP traffic. Without sending, receiving, and verifying application data over a UDP socket, there is no guarantee that a remote UDP port is open and accepting packets.
Now you can repeat the same connection test but using IPv6. Run the following netcat command:
You should receive output like the following:
The output indicates that netcat did not receive an error from the UDP socket listening on the loopback ::1 IPv6 address on port 123 . Again, this lack of an error response is used to infer that the socket at ::1:123 is available.
To clean up your sockets, you’ll need to run the fg (foreground) command for each socat process that you created. Then you’ll use CTRL+C to close each socat.
Run fg to bring the second IPv6 socat instance to the foreground of your terminal. Then run CTRL+C to close it.
You will receive output like the following:
Press CTRL+C to stop the process.
Now run fg again to clean up the first IPv4 socket. You will have output like the following:
Press CTRL+C to stop the process.
You have now created, examined, and tested IPv4 and IPv6 UDP sockets on your system. Try experimenting with each tool to become more familiar with how they can be used to test and troubleshoot UDP sockets.
What is a Unix Domain Socket?
Programs that run on the same server can also communicate with each other using Unix Domain Sockets (UDS). Unix Domain Sockets can be stream-based, or datagram-based. When using domain sockets, data is exchanged between programs directly in the operating system’s kernel via files on the host filesystem. To send or receive data using domain sockets, programs read and write to their shared socket file, bypassing network based sockets and protocols entirely.
Unix Domain Sockets are used widely by database systems that do not need to be connected to a network interface. For example, MySQL on Ubuntu defaults to using a file named /var/run/mysqld/mysql.sock for communication with local clients. Clients read from and write to the socket, as does the MySQL server itself.
PostgreSQL is another database system that uses a socket for local, non-network communication. Typically it defaults to using /run/postgresql/.s.PGSQL.5432 as its socket file.
Creating Unix Domain Sockets
In the previous sections you explored how TCP is used with stream sockets, and how UDP is used with datagram sockets. In this section you’ll use socat to create both stream-based and datagram-based Unix Domain Sockets without using TCP or UDP to encapsulate data to send over networks. Then you’ll examine the sockets that you create using the ss , and nc commands. Finally, you’ll learn about testing Unix Domain Sockets using netcat.
To get started, run the following socat commands to create two socket files:
- The first command instructs socat to create a socket using the unix-listen address type, which will create a stream-based UDS.
- The second command specifies unix-recvfrom as the socket type, which will create a datagram-based UDS
- Both commands specify a filename after the : separator. The filename is the address of the socket itself. For the first stream example it is /tmp/stream.sock and for the second datagram example it is /tmp/datagram.sock . Note that the name of a socket is arbitrary but it helps if it is descriptive when you are troubleshooting.
- The fork , and /dev/null arguments are used in the same manner as described in the Stream and Datagram socket example sections.
Now that you have created your two UDS sockets, you can examine them using the ss and nc utilities.
Examining Unix Domain Sockets
To list all listening Unix Domain Sockets, run the ss -xln command. The x flag ensures that only domain sockets are displayed.
You will receive output like the following:
Notice the highlighted u_str portion of the /tmp/stream/sock line. This field indicates that the socket type is a stream-based UDS. The second line shows the type is u_dgr which means the socket type is datagram-based.
Since Unix Domain Sockets are files, the usual Linux user and group permissions and access controls can be used to restrict who can connect to the socket. You can also use filesystem tools like ls , mv , chown and chmod to examine and manipulate UDS files. Tools like SELinux can also be used to label UDS files with different security contexts.
To check if a file is a UDS socket, use the ls , file or stat utilities. However, it is important to note that none of these tools can determine if a UDS is stream or datagram-based. Use the ss tool for the most complete information about a Unix Domain Socket.
To examine a socket on the filesystem, the stat utility shows the most relevant information. Run it on the sockets that you created earlier:
You will receive output like the following:
Notice that for each file, the type is socket (highlighted at the far right of the output) and the access mode has an s character preceding the file’s permissions.
The ls utility will also indicate if a file is a socket. Run ls -l to examine the files:
You will receive output like the following. Again note that for sockets, the file mode includes the s character before the file permission fields:
Now that you have created Unix Domain Sockets, and learned how to examine them using the ss and various filesystem based tools, the next step is to test the sockets using a tool like netcat.
Testing Unix Domain Sockets
The netcat utility can be used to connect to Unix Domain Sockets, as well as TCP and UDP sockets that you already learned about earlier in this tutorial. To connect to the example sockets that you created, you will need to specify an extra -U flag when running the netcat command. This flag tells netcat to connect to a UDS, as opposed to a TCP or UDP based network socket.
Additionally, if the socket is datagram-based, you will use the -u flag to instruct netcat to use datagrams as we learned in the Datagram Socket section of this tutorial.
Let’s start examining UDS sockets by connecting to the stream-based socket with the following command:
The -U tells netcat that it is connecting to a Unix Domain Socket.
The — z option ensures that netcat only connects to a socket, without sending any data.
The /tmp/stream.sock is the address of the socket on the filesystem.
You will not receive any output from netcat when you run the command. However, if a socket is not available, netcat will output an error message like the following:
So the absence of output from netcat when testing a stream-based UDS socket means that the connection was successful.
Repeat the testing process, this time for the datagram-based UDS:
The additional -u flag is added to tell netcat that the remote socket is a datagram socket. Again, you will not receive any output if the test is successful.
If there is no socket at the address, you will receive an error like the following:
To clean up your sockets, you’ll need to run the fg (foreground) command for each socat process that you created. Then you’ll use CTRL+C to close each socat.
Run fg to bring the datagram-based socat instance to the foreground of your terminal:
You will receive output like the following:
Run CTRL+C to close it. You will not receive any output.
Now run fg again to clean up the first stream-based UDS socket.
Again you should have output like the following:
Run CTRL+C to end the process. You will not receive any output.
You have now created, examined, and tested Unix Datagram Sockets sockets on your system. Try experimenting with netcat and socat to become more familiar with how you can send and receive data over a UDS, as well as how you can test and troubleshoot Unix Domain sockets.
Conclusion
In this tutorial you explored how different kinds of sockets are used on a Linux system. You learned about stream-based sockets, which typically use TCP for network communication. You also learned about datagram-based sockets, which use UDP to send data over networks. Finally, you explored how Unix Domain Sockets can be either stream or datagram-based on a local server.
In each section you used the ss utility to gather information about sockets on a Linux system. You learned how the different flags that the ss tool provides can help you limit its output to specific types of sockets when you are examining sockets on a system.
Finally, you used the netcat and socat tools to create and connect to each of the three different types of sockets discussed in this tutorial. The netcat utility is widely used to connect to sockets, but it can also create sockets. Its documentation ( man nc ) contains many examples of how it can be used in either mode. The socat utility is a more advanced tool that can be used to connect to and many different types of sockets that are not covered in this tutorial. Its documentation ( man socat ) also contains numerous examples of the different ways that it can be used.
Understanding what sockets are and how they work is a core system administration skill. The tools and techniques that you experimented with in this tutorial will help you become more familiar with sockets, and how to troubleshoot them if your servers and applications are not communicating with each other correctly.
Источник