This post series aims to clarify the different operations you could do with a network socket and the verbs to use when talking about them. So what is a socket and why should I care about things I could do with it? From Wikipedia: A network socket is an endpoint of a connection in a computer network. It is a handle (abstract reference) that a program can pass to the networking application interface (API) to use the connection for receiving and sending data. Sockets are often represented internally as integers. programming So, if your application is using sockets in some way, and it most probably is, you should be familiar with the operations on sockets. Let’s start by creating a socket. Creating a socket Creating a socket is done via the system call. To create a socket we need to specify 3 things — this is the signature of the socket method: socket #include <sys/types.h> #include <sys/socket.h> int socket(int domain , int type , int protocol ); So, what are domain, type and protocol? Domain specifies the protocol family which will be used for communication. A protocol family is a group of logical properties within an interface configuration. Protocol families include all the protocols that make up a protocol suite. The most popular ones are IPv4, IPv6, UNIX. network The type describes the semantics of the protocols that are part of the protocol family specified by the previous argument — e.g. I want to have a 2-way connection oriented byte streams with guarantee of delivery, or I just want to send datagrams (connectionless, unreliable messages of a fixed maximum length). Ok, so we have specified the protocol family, and what we want from it. The last argument specifies a concrete protocol implementation from the family. In general, there is only one protocol that satisfies the (family, type) pair, so this argument is omitted ( is passed), but if more than one implementations exist, this argument must be set accordingly. 0 After we have created the socket, we could either connect to a remote socket, or listen for incoming connections. Let’s start with the later. Binding address to socket In order to listen for incoming connections, or just to receive datagrams, we first need to specify an address for the socket (think of it as assigning a name to the socket). This operations is called binding — we an address (name) to the socket. bind sockfd, int bind(int const struct sockaddr * ); addr, addrlen socklen_t This call takes the socket descriptor, the address which should be used and the size in bytes of the address type. The actual structure passed for the argument will depend on the address family (we talked about protocol families earlier, remember?). The only purpose of the structure is to cast the structure pointer passed in in order to avoid compiler warnings. Let’s see an example for binding the 127.0.0.1:8000 IPv4/TCP address to a socket. (Error handling is omitted for simplicity) addr struct sockaddr addr int sockfd;struct sockaddr_in serv_addr; sockfd = socket(PF_INET, SOCK_STREAM, 0); memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET;serv_addr.sin_addr.s_addr = INADDR_LOOPBACK;serv_addr.sin_port = htons(8000); bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); Great! We now have address associated with the socket. If we had specified a connectionless protocol, e.g. UDP, we could start reading directly from the socket. But since we chose a connection-oriented protocol, TCP, we should announce willingness to accept incoming connections and then read data from those connections. Let’s see how this happens. Listening on a socket Listening is done via the system call: listen sockfd, backlog**);** int listen(int int The first arguments is the socket we want to listen on, and the second one specifies a so-called backlog. A queue for pending incoming connections is created (by the OS) for each socket. The backlog represents the size of the queue. If a connection request arrives when the queue is full, the client may receive an error or the request may be ignored (depending on the underlying protocol). Note that the queue size might be affected by some protocol specifics or OS configurations, thus it might not take the value specified via . listen Accepting incoming connections After we announced that we want to accept connections, the last part is to actually accept such. This is done via (surprise!) the syscall. accept sockfd, *****addr, int accept(int struct sockaddr socklen_t * ); addrlen is the socket we earlier listened on. The argument is a pointer to a structure. This structure is filled in with the address of the peer socket (client’s address), as known to the communications layer. The exact format of the address returned is determined by the socket’s address family. If we do not care about the peer address, we can just pass . sockfd addr sockaddr NULL The argument is a value-result argument: the caller must initialize it to contain the size (in bytes) of the structure pointed to by . On return it will contain the actual size of the peer address. addrlen addr Example Let’s put it all together. Note that the below example will exit only if there’s error when trying to accept an incoming connection. After building and running, we could verify that the behavior is correct. First, let’s see that the program is listening on the desired address: $ ss -tnl src :8000State Recv-Q Send-Q Local Address:Port Peer Address:PortLISTEN 0 128 *:8000 *:* You can see that we have a socket in state. The local address of the socket is , which corresponds to that we’ve configured. The size is , as specified by the arg of the syscall. TCP LISTEN *:8000 INADDR_ANY:8000 Send-Q 128 backlog listen If we establish a connection to our program using , we see the “Hello, socket!” message. netcat $ nc localhost 8000Hello, socket! And the output of our program prints the peer’s address (127.0.0.1 if we’re connection from the same machine): $ ./mainreceived connection from peer: 127.0.0.1 Summary In this post we explained the purpose of the , , and actions on sockets. Let’s reiterate. socket bind listen accept socket In the next part of the series, we’ll look from a client’s perspective by initiating a connection on a socket, sending and receiving data and cleaning after ourselves. Stay tuned. is how hackers start their afternoons. We’re a part of the family. We are now and happy to opportunities. Hacker Noon @AMI accepting submissions discuss advertising &sponsorship To learn more, , , or simply, read our about page like/message us on Facebook tweet/DM @HackerNoon. If you enjoyed this story, we recommend reading our and . Until next time, don’t take the realities of the world for granted! latest tech stories trending tech stories