Socket Programming
Table of Contents
OSI 7 Layer #
OSI 7 layers in computer system can be used to explain Networking systems. TCP/IP communication protocols goes are at the Transport Layer and the HTTP protocol is on the most top Application Layer.
Even if OSI Layer is provided, still it is complicated to develop network program. Socket Programming makes you develop program without having deep understandings in TCP/IP protocol. Socket is located in Transport Layer in OSI 7 layer. (Also there are Raw Socket that users can control into Network Layer also)
Network & Process #
Sockets allow communication between two different processes on the same or different machines. Normally, Internet seemed to connect one computer to another computer. However, for developers, we must realize the internet is the connection between processes on same or different machines. For example, just like Chrome(client-side) to Apache Server(server-side).
There are several Internet service models, but for this course, we’re going to focus on Server-Client Model.
- Server-Client Model
- P2P (Peer-to-Peer) Model
- Agent/Manager Model
Using multi-process we can use several network services on one computer. Each service are differentiated using different port numbers. Every service have its own port numbers. From 1 ~ 1023, there are already explicitly declared port number.
Clients and Servers are connected through ports. Ports must be specified to connect wanted program. Ports are mostly fixed for servers, however for clients it is randomly chosen by OS.
Network Programming #
To send or receive data between processes in network, we should use sockets. The photo below show brief steps and methods how socket programming works.
Sockets are also called as BSD(berkely sockets) socket. Which was founded at UC Berkely at 1989 and still be used. Network programs can be widely used no regard to OS because, almost every OS is using BSD sockets.
Steps of Socket Programming #
The list below represents basic steps and methods to implement socket programming.
- socket function : create sockets
bind
function : define sockets’ propertieslisten
function : prepare server for incoming client requests (applies to stream sockets)- Connection between system
connect
function : try to connect from clientaccept
function : accept connection from server
- read & write function : data communication
- close function : close socket
socket #
int socket(int domain, int type, int protocol);
Windows: winsock2.h
Linux: sys/socket.h
BSD sockets are located at the header files.
Sockets are used by 2 different purpose, to connect and listen. For client it is connected socket, and for server it is called listen socket.
Parameters:
- domain
- AF_UNIX → used in IPC(Inter-Process Communication)
- AF_INET → used in Internet Communication
- AF_INET6 → same as AF_INET using IPv6
- AF_X25 → used in Radio Protocol
- type
- SOCK_STREAM → connection oriented TCP/IP based communication
- SOCK_DGRAM → Datagram UDP/IP based communication
- SOCK_RAW → using Raw Socket mentioned above
- protocol
- IPPROTO_TCP → TCP protocol used with AF_INET and SOCKET_STREAM
- IPPROTO_UDP → UDP protocol used with AF_INET and SOCKET_DGRAM
- return
Data type: int
Return value-1
→ Fail- returns sockfd (listening socket descriptor, which is integer)
bind #
int bind(SOCKET sockfd, const struct sockaddr *my_addr, socklen_t namelen)
// sockfd:
struct sockaddr {
// AF_INET
unsigned short sa_family;
char sa_data[14];
}
struct sockaddr_in {
short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}
struct sockaddr_un {
unsigned short sin_family;
char sun_path[108];
}
// Example of bind function
int bind_lsock(int lsock, int port) {
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
return bind(lsock, (struct sockaddr*)&sin, sizeof(sin));
}
listen #
int listen(int sockfd, int backlog);
If new request from client have received before ongoing request is finished, there must be a queue to wait for the previous request to be finished. listen function is used to create this queue.
Parameters:
- sockfd
- backlog → the size of queue
- return
Data type: int
Return value-1
→ Fail0
→ Success
accept #
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// Example
while(1) {
client_addr_size = sizeof(client_addr);
client_sockfd = accept(sockfd, (struct sockaddr *) &client_sockaddr,
&client_addr_size);
if (client_sockfd == -1) {
//error
}
}
accept function brings first request from the queue which was created by listen function.
Also, there are connect function which is almost identical with accept function. But, connect function is for client and also doesn’t create new socket.
int connect(int sockfd, const struct sockaddr *serv_addr, socklen_t addrlen);
Parameters:
- sockfd
- addr → If succeeded, struct with connected client’s address and port information
- addrlen → size of struct sockaddr
- return
Data type: int
Return value-1
→ Fail- returns sockfd (But different with return value of socket function) listen socket is only for getting request and put into queue. but the receiving request and communicating process must be distinguished to get another request from client while communicating others. (Often using multi-process or multi-thread)
read & write #
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
ssize_t write(int fd, const void *buf, size_t count);
For communicating data, read and write functions are used. For read & write function, there are two types. One is basic function provided by OS, and the other is provided in socket.
In linux, everything including sockets are handled as a file. So, read & write system functions are also used for socket.
Parameters:
- sockfd client-side → socketfd created by socket function server-side → socketfd created by accept function
- buf → If succeeded, struct with connected client’s address and port information
- count → size of struct sockaddr
- return
Data type: int
Return value-1
→ Fail- returns the byte size of data
close #
#include <unistd.h>
int close(int sockfd);
Remaining socket will keep taking possessions of system resources. So, we must close socket using this function.
return
Data type: int
Return value
-1
→ Fail0
→ Success
Reference #
- https://www.cs.dartmouth.edu/~campbell/cs50/socketprogramming.html
- https://www.ibm.com/docs/en/zos/2.4.0?topic=functions-listen-prepare-server-incoming-client-requests
- https://www.ibm.com/docs/en/ztpf/1.1.0.14?topic=functions-close-shut-down-socket
- https://helloworld-88.tistory.com/215
- https://codingfarm.tistory.com/534?category=812608