Linux Network Programming: A simple implementation of client/server

Source: Internet
Author: User

First, Socket basic knowledge 1. Socket function

Socket hierarchy

The socket essentially provides the endpoint of the process communication, before the process communicates, the two parties must first create an endpoint individually, otherwise there is no way to establish contact and communicate with each other.

Each socket is a semi-related description:

{protocol, local address, local port}

Description of the complete socket:

{protocol, local address, local port, remote address, remote port}

2. Socket Workflow

Connection-oriented (TCP) socket workflow

Socket workflow for UDP

L Server-side

First, the server application uses the system call socket () to create a socket, which is a resource of a similar file descriptor that the system assigns to the server process and cannot be shared with other processes.

Next, you need to bind to the socket, where the local socket is bound to the file name in the Linux file system, usually in the/TMP or/usr/tmp directory. For a network socket, the service identifier (port number or access point) that is associated with the specific network to which the customer is connected. The socket can be bound using the system call bind (), and then the server process creates a queue with listen () to queue the client's connection and then receives the client's connection using accept ().

When the server calls accept (), it creates a new socket that is different from the original socket. This new socket is only used to communicate with this particular customer, and the original socket remains to process connections from other customers.

L Client

The client is the first to call the socket () to create an unbound socket and then call Connect () to connect with the server as an address.

3. Socket Properties

L Socket Domains (domain)

L Types of sockets (type)

There are three types of sockets: Streaming Sockets (SOCK_STREAM), datagram Sockets (SOCK_DGRAM), and raw sockets.

Streaming Sockets (SOCK_STREAM)

Streaming sockets can provide reliable, connection-oriented traffic flows. If you send sequential data through a streaming socket: "1", "2", then the data arrives in the order "1", "2". Streaming sockets use the TCP protocol in the AF_INET domain to ensure the correctness and sequencing of data transmission. TCP is the first half of the TCP/IP protocol, which only handles network routing.

Datagram Sockets (SOCK_DGRAM)

Datagram Protocol defines a non-connected service that transmits data through separate messages, is unordered, and is not guaranteed to be reliable and error-free. It uses the UDP/IP protocol. UDP packs The data, stickers the IP address, and sends it. This process does not need to establish a connection.

Raw sockets

The original socket is mainly used for the development of some protocols and can be compared with the underlying operations. It is powerful, but no streaming sockets and datagram sockets are easy to use, and the general program does not involve the original sockets.

4. Socket address

Af_inet and Af_unix domain socket address structure is not the same, respectively, the struct sockaddr_in, struct sockaddr_un.

L AF_INET Address structure

#include <netinet/in .h>struct sockaddr_in{shortint/* af_inet * /  Short int / * Port numbers*/ struct / * Internet Address */}

The IP address structure in_add is defined as:

struct Long int / * The IP address is a 32-bit value of four bytes */}

L AF_UNIX Address structure

#include <sys/un.h>struct/* Af_unix */char/* pathname */}

In the current Linux system, the type sa_family_t defined by the X/open specification is declared in the header file Sys/un.h, which is a short integer type. The length of the pathname specified by the Sun_path is also limited (Linux specifies 108 characters).

Second, the conversion function

1. Host byte order and network byte order

Because each machine inside the variable byte storage order is different (some systems are high in front, low in the back, some systems are low in front, high in the rear), and the network transmission of the byte order needs to be unified. Therefore, for machines with different host byte order and network byte order, the data must be converted (for example, the representation of IP address and the representation of the port number). If the host byte order is the same as the network byte order, the conversion function is also called, and the actual conversion or not conversion is determined by the system function itself.

Conversion functions:

#include <netinet/inlongintlongint/* Host to network long */  Shortintshortint/* Host to network short */long  intlongint/* Network to host long */shortintshort  int/* Network to host short * /

These functions convert both 16-bit and 32-bit integers between the host byte order and the standard network byte order. "H" stands for Host "hosts", "N" stands for "Network", "L" stands for "long" and "s" stands for "short".

Third, socket system call

1. Creating socket Sockets ()

The socket () system call creates a socket and returns a descriptor that can be used to access the socket.

#include <sys/types.h> #include <sys/socket.h>int sockets (int int int protocol);

The socket created is an endpoint of a communication line, and the domain parameter specifies the protocol family, the type parameter specifies the type of communication for this socket, and the protocol parameter specifies the protocol used.

The most common socket fields are Af_unix and af_inet, which are used for local sockets implemented through UNIX and Linux file systems, which are used for UNIX network sockets. Af_inet sockets can be used for programs that communicate through a TCP/IP network, including the Internet.

The parameter type specifies the type of communication for this socket, and the protocol parameter specifies the protocol used. The protocol required for communication is generally determined by the socket type, and usually does not require a selection. The protocol parameter is used only when a selection is required. Setting the protocol parameter to 0 means using the default protocol.

The socket returns a descriptor, similar to a file descriptor. This descriptor can be used for read (), write () and other system notes to connect to another socket.

Example: Create a socket,af_inet,sock_stream.

SERVER_SOCKFD = socket (af_inet, sock_stream, 0);

2. Bind socket

After you call the socket () to get the descriptor, you need to bind the socket. The Af_unix socket is associated with the pathname of a file system, and the af_inet socket is associated to an IP port number.

#include <sys/socket.h>int bind (intconststruct sockaddr *address, size_t Address_len);

Bind assigns the address in the parameter address to the unnamed socket associated with the file descriptor socket. Address_len passes the length of the address structure body. The length of the address depends on the type of address. Bind system calls require a struct sockaddr_in or struct sockaddr_un pointer to be converted to a struct sockaddr * type.

Bind returns 0 when the call succeeds, the failure is 1 and the errno is set.

EBADF

Invalid file descriptor

Enotsock

The file descriptor does not correspond to a socket

EINVAL

The file descriptor corresponds to a socket that is already bound

Eaddrnotavail

Address Not available

Eaddrinuse

The address is already bound to a socket

Table 2 errno values

Af_unix also has some error codes

Eaccess

Insufficient permissions to create path names in the file system

Enotdir, Enametoolong

File name does not meet the requirements

Table 3 Af_unix Partial errno values

Instance:

Bind (SERVER_SOCKFD, (struct sockaddr *) &server_address, Server_len);

3. Create a socket queue

To be able to accept the incoming link on the socket, the server establishes a queue to hold the unhandled request.

#include <sys/socket.h>int Listen (intint backlog);

The parameter backlog sets the maximum number of unhandled connections that can be accommodated in the queue. After this number is exceeded, the remaining connections are rejected. The usual value of the backlog is 5 ...

The Listen function returns 0 on success, 1 on failure, and the error code includes ebadf,einval and Enotsock.

Instance:

Listen (SERVER_SOCKFD, 5);

4. Accept the connection

Once the server program creates and binds the socket, he can wait for the client to establish a connection to the socket by using accept ().

#inculde <sys/socket.h>int accept (intstruct sockaddr *address, size_t *address_len) ;

Accept returns only if a client program tries to connect to the socket specified by the socket parameter. Accept will create a new socket to communicate with the customer, with the socket descriptor as the return value. Subsequent read and write actions are associated with the socket descriptor.

The socket associated with the parameter socket must first have been bound by bind, and there is listen to assign the connection queue to it. The address of the parameter represents the customer's addresses, which can be set to a null pointer if the customer's address value is not cared for.

If the socket does not have an unhandled connection, accept will block until there is an unhandled connection in the queue. Can be changed by setting O_nonblock. Instance:

int flags = FCNTL (socket, F_GETFL, 0); Fcntl (socket, F_SETFL, O_nonblock | flags);

When an error occurs, accept returns-1.

5. Request a connection

The client program connects to the server through a method that is bound to the server listening socket.

#include <sys/socket.h>int connect (intconststruct sockaddr *address, size _t Address_len);

The socket specified by the socket will be connected to the socket on the server specified in the parameter address.

On success, connect returns 0, and the failure returns-1.

If the connection cannot be established immediately, connect will block to the timeout time, the connection will be discarded and the connection fails.

6. Close the socket

You can use Close () to terminate the server's socket connection to the client.

#include <unistd.h>int close (int socket);

7. Sending data Send ()

Send () also sends data, unlike write (), send () can only be used for sending socket data.

#include <sys/socket.h>int send (intconstvoidintint ) Flags

parameter, the buff points to the data to be sent, Len is the length of the data to be sent, and the flags are typically 0.

On success, send returns the number of bytes sent, and the failure returns-1.

8. Receive Data recv ()

As with Send (), recv () can only be used to send data to the socket.

#include <sys/socket.h>int recv (intvoidintint , flags)

The BUF points to the buffer that holds the received data, Len is the data length, and the flags are typically 0.

On success, recv () returns the number of bytes received, which returns 1 on failure.

9. Send Data SendTo ()

SendTo need to bring the address information of the sending destination, can be used for the implementation of UDP communication, TCP can also use SendTo ().

#include <sys/socket.h>int sendto (intconstvoidint int) Const struct int Addr_len)

The buff points to the data to be sent, Len is the length of the data to be sent, and flags generally carry the information for the destination IP that 0,addr_to carries, and Addr_len is the length of the address information.

On success, SENDTO returns the number of bytes sent, and the failure returns-1.

10. Receive Data Recvfrom ()

Recvfrom () and sendto supporting the use, to achieve data transmission and receiving.

#include <sys/socket.h>int recvfrom (intconstvoidintint)  conststructint addr_len)

The buff points to the buffer that receives the data, Len is the data length, flags is typically 0, Addr_from holds the IP address of the data source, and Addr_len is the length of the address information.

The Recvfrom returns the number of bytes received when successful, and the failure returns-1.

Iv. obstruction

Connect (), recv () is a blocking function, and when the resource of the requirement is not ready, the process that invokes the function goes into hibernation, so that I/O multiplexing cannot be handled.

The workaround for this problem is the same as for normal file operations: Use the FCNTL () or select () function. Compared to Fcntl (), the Select () function can also set the wait time for more powerful functions.

----<end>----

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.