1. Socket and fundamental concepts
1.1 Definition
- A socket is communication mechanism that allow client/server system to be developed either locally, on a single machine, or across networks. Linux function such as printing, connecting to database, and serving web pages as well as network utilities such as rlogin for remote login and ftp for file transfer usually use sockets to communicate
- Another definition: A socket is just a logical endpoint for communication. They exist on the transport layer. You can send and receive things on a socket, you can bind and listen to a socket. A socket is specific to a protocol, machine, and port, and is addressed as such in the header of a packet.
- A simple definition: A network socket is one endpoint in a communication flow between two programs running over a network
A simple socket model
There are two types of socket used widely: stream sockets and datagram sockets
- Stream Sockets (based on TCP protocol): is a stream oriented protocol. Delivery in a networked environment is guaranteed. If you send through the stream socket three items "A, B, C", they will arrive in the same order - "A, B, C". These sockets use TCP (Transmission Control Protocol) for data transmission. If delivery is impossible, the sender receives an error indicator. Data records do not have any boundaries.
- Datagram Sockets (based on UDP protocol): is a message oriented protocol. Delivery in a networked environment is not guaranteed. They're connectionless because you don't need to have an open connection as in Stream Sockets - you build a packet with the destination information and send it out. They use UDP (User Datagram Protocol)
Most of the Net application use the Client-Server architecture, which refers to two processes or two applications that communicate with each other to exchange some information. One of the two processes acts as a client process and another process acts as a server.
- Client process: This is the process, which typically makes a request for information. After getting the response, this process may terminate or may do some other processing. Example: Internet Browser (Chrome, Firefox, ..) works as a client application, which sends a request to the Web Server to get one HTML web page.
- Server process: This is the process which takes a request from the clients. After getting a request from the client, this process will perform the required processing, gather the requested information, and send it to the request client. Once done, it becomes ready to server another client. Server processes are always alert and ready to serve incoming requests. Example: A web page server waiting for requests from Internet Browsers.
- Iterative Server: This is the simplest form of server where a server process serves one client and after completing the first request, it takes request from another client. Meanwhile, another client keeps waiting.
- Concurrent Servers: This type of server runs multiple concurrent processes to serve many requests at a time because one process may tke longer and another client cannot wait for so long. The simplest way to write a concurrent server under Unix is to fork child process to handle each client separately
How to request a specific service
For our different purposes, ports will be defined as an integer number between 1024-65535
The port assignments to network services can be found in the file /etc/services. If you are writing your own server then care must be taken to assign a port to your server. You should make sure that this port should not be assigned to any other server.
2. Socket connection
First, a server process gives the socket a name. Local sockets are given a filename in the Linux file system, often to be found in /tmp or /usr/tmp. For network sockets, the filename will be a service identifier allows Linux to route incoming connections specifying a particular port number to the correct server process.
2.1 Socket parameter
ü The protocol (TCP, UDP, …)
ü The local address
ü The remote address
ü The local port number
ü The remote port number
Socket Parameter
Establish a socket connection
2.3 Core functions
Creating a socket
Socket Addresses: Each socket domain requires its own address format.
1
2
| int socket( int domain, int type, int protocol); } |
1
2
3
4
| struct socketaddr_un { sa_family_t sun_family; char sun_path[]; } |
1
2
3
4
5
| struct sockaddr_in { short int sin_family; // AF_INET unsighed short int sin_port; // port number struct in_addr sin_addr; // Internet address } |
1
2
3
| struct in_addr { unsigned long int s_addr; }; |
To make a socket available for use by other processes, a server program needs to give the socket a name
#include <sys/socket.h>
int bind(int socket, const struct sockaddr *address, size_t address_len)
Creating a Socket Queue
#include <sys/socket.h>
int listen(int socket, int backog)
Accepting Connections
Once a server program has created and named a socket, it can wait for connections to be made to the socket by using the accept call
#include <sys/socket.h>
int accept(int socket, struct sockaddr *address size_t *address_len)
Requesting connections
Client program connect to servers by establishing a connection between an unnamed socket and the server listen socket
#include <sys/socket.h>
int connect(int socket, const struct socketaddr *address, size_t address_len);
Close a socket
You should always close the socket at both ends.
3. Unix internal Socket and Unix network Socket
3.1 Unix internal Socket - Creating local Socket
You can download source here
3.2 Unix network Socket - Creating network Socket
You can download source here
4. Multiple client using fork()
4.1 Concurrent server
Server can serve more than one client in a time. We can see the way server do that by fork() to create child processes
Client connects to child server
Two clients connect to two child servers
Status of client/server when client request connection
Status of client/server after return from accept
Status of client/server after fork return
Status of client/server after parent and child close appropriate sockets
4.3 Outline for typical concurrent server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| pid_t pid; int listenfd, connfd; listenfd = Socket( ... ); /* fill in sockaddr_in{} with server's well-known port */ bind(listenfd, ... ); listen(listenfd, LISTENQ); for ( ; ; ) { connfd = accept (listenfd, ... ); /* probably blocks */ if ( (pid = fork()) == 0) { close(listenfd); /* child closes listening socket */ doit(connfd); /* process the request */ close(connfd); /* done with this client */ exit (0); /* child terminates */ } close(connfd); /* parent closes connected socket */ } |
Code full:
4.4 Prevent zombie process
Using fork() to create child process to handle connections from clients causes “zombie process”. Obviously we do not want to leave ombies around. They take up space in the kernel and evenrually can run out of processes. We need to prevent that by handling SIGCHLD Signals. Whenever we fork children, we must wait for them to prevent them from becoming zombies. To di this, we establish a signal-handle to catch SIGCHLD, and within the handler, we call wait. We establish the signal handler by adding the function call
Signal(SIGCHLD, sig_chld);
References
Beginning Linux Programming
Unix network programming
Không có nhận xét nào:
Đăng nhận xét