Linux C Programming-Network Programming

Source: Internet
Author: User
Tags new set htons
Linux C Programming-Network Programming
Summary

Network programming must be inseparable from a set of interfaces. What is a set of interfaces? In Linux, All I/O operations are generated by reading and writing file descriptors, which are integers associated with opened files, this file does not only contain files actually stored on disks, but also contains a network connection, a named pipe, and a terminal, A set of interfaces is a way for system processes to communicate with file descriptors. Currently, the most common set of interfaces are: byte stream set interface (based on TCP) and datagram set interface (based on UDP ), of course, there are also Original Sets of interfaces (the original sets of interfaces provide functions not provided by TCP sets and UDP sets, such as constructing their own TCP or UDP groups, here we mainly introduce the byte stream set interface and the datagram set interface.

(13:40:14)

By Wing

Network programming must be inseparable from a set of interfaces. What is a set of interfaces? In Linux, All I/O operations are generated by reading and writing file descriptors, which are integers associated with opened files, this file does not only contain files actually stored on disks, but also contains a network connection, a named pipe, and a terminal, A set of interfaces is a way for system processes to communicate with file descriptors. Currently, the most common set of interfaces are: byte stream set interface (based on TCP) and datagram set interface (based on UDP ), of course, there are also Original Sets of interfaces (the original sets of interfaces provide functions not provided by TCP sets and UDP sets, such as constructing their own TCP or UDP groups, here we mainly introduce the byte stream set interface and the datagram set interface.

To learn network programming, you must be inseparable from the functions of the network library. in Linux, you can use the "Man function name" to get help from this function, but to take care of friends who are not very good at E-wen, the following lists common network functions and usage for your reference:

1. socket function: to execute network input and output, the first thing a process must do is to call the socket function to obtain a file descriptor.

--------------------------------------------------------------- # Include <sys/socket. h> int socket (INT family, int type, int Protocol); Return: non-negative descriptive word --- success-1 --- failed response -----------------------------------------------------------------

The first parameter specifies the protocol cluster. Currently, five protocol clusters are supported. af_inet (IPv4 protocol) and af_inet6 (IPv6 Protocol) are most commonly used. The second parameter specifies the set of interface types, three types are available: sock_stream (byte stream set Interface), sock_dgram (datagram set Interface), and sock_raw (original set interface). If the set interface type is not the original set interface, the third parameter is 0.

2. Connect function: After socket is used to establish a set of interfaces, you can call connect to specify the remote address for this socket. If it is a byte stream set interface, connect uses a three-way handshake to establish a connection. If it is a datagram set interface, connect only specifies the remote address and does not send any data to it.

Counter # include <sys/socket. h> int connect (INT sockfd, const struct sockaddr * servaddr, socklen_t addrlen); Return: 0 --- success-1 --- failed counter -----------------------------------------------------------------

The first parameter is the set interface description returned by the socket function. The second and third parameters are a pointer pointing to the set interface address structure and the size of the structure.

These address structures start with sockaddr _ and end with a unique suffix for each protocol family. Take the IPv4 address structure as an example. It is named "sockaddr_in" and is defined in the header file <netinet/in. h>. The following is the structure content:

Explain struct in_addr {in_addr_t s_addr;/* IPv4 address */}; struct sockaddr_in {uint8_t sin_len;/* unsigned 8-bit integer */sa_family_t sin_family; /* address cluster of the interface address structure, which is af_inet */in_port_t sin_port;/* TCP or UDP port */struct in_addr sin_addr; char sin_zero [8];};

3. Bind function: assign a local IP address and protocol port to the set interface. For Internet protocol, the Protocol address is a combination of 32-bit IPv4 address or 128-bit IPv6 address and 16-bit TCP or UDP port number. If the specified port is 0, the kernel selects a temporary port when BIND is called, if a wildcard IP address is specified, the kernel selects a local IP address only after the connection is established.

Counter # include <sys/socket. h> int BIND (INT sockfd, const struct sockaddr * myaddr, socklen_t addrlen); Return: 0 --- success-1 --- failed counter -------------------------------------------------------------------

The first parameter is the set of interface descriptions returned by the socket function. The second and third parameters are a pointer to the Protocol-specific address structure and the length of the address structure.

4. Listen function: The listen function is called only by the TCP server. Its function is to convert an active set interface created with sock into a passive set interface and wait for connection requests from the client.

------------------------------------------------------------------- # Include <sys/socket. h> int listen (INT sockfd, int backlog); Return: 0 --- success-1 --- fail -------------------------------------------------------------------

The first parameter is the set interface description returned by the socket function. The second parameter specifies the maximum number of connections that the kernel queues for this set of interfaces. Because of the second parameter of the listen function, the kernel maintains two queues: to complete the connection queue and to complete the connection queue. The unfinished queue stores the three-way handshake of the TCP connection, and the accept function retrieves the connection from the connection queue and returns it to the process. When the connection queue is empty, the process enters the sleep state.

5. Accept function: the accept function is called by the TCP server. A completed connection is returned from the completed connection queue header. If the completed connection queue is empty, the process enters the sleep state.

Counter # include <sys/socket. h> int accept (INT sockfd, struct sockaddr * cliaddr, socklen_t * addrlen); Back: non-negative descriptive word --- success-1 --- failed response -------------------------------------------------------------------

The first parameter is the set interface description returned by the socket function. The second and third parameters are the set interface address structure pointing to the connector and the length of the address structure respectively; this function returns a brand new set of interface descriptions. If you are not interested in the information of the customer segment, you can leave the second and third parameters blank.

6. inet_pton function: converts a dot-decimal string to a binary value in the byte sequence of the network. This function can handle both IPv4 and IPv6 addresses.

------------------------------------------------------------------- # Include <ARPA/inet. h> int inet_pton (INT family, const char * strptr, void * addrptr); Return: 1 --- success 0 --- input is not a valid expression format-1 --- failure success -------------------------------------------------------------------

The first parameter can be af_inet or af_inet6: The second parameter is a pointer to the dot-decimal string. The third parameter is a pointer to the binary value of the converted network in the byte sequence.

7. inet_ntop function: opposite to inet_ton function, inet_ntop function converts the binary values in the byte sequence of the network to a dot-decimal string.

------------------------------------------------------------------- # Include <ARPA/inet. h> const char * inet_ntop (INT family, const void * addrptr, char * strptr, size_t Len); Return: pointer to result --- success null --- fail -------------------------------------------------------------------

The first parameter can be af_inet or af_inet6: The second parameter is a pointer to the binary value in the byte sequence of the network. The third parameter is a pointer to the converted dot-decimal string; the fourth parameter is the size of the target to avoid function overflow.

8. Fock function: In a network server, a service port can allow a certain number of clients to connect at the same time, which is impossible for a single process, the Fock allocates a sub-process and client session. Of course, this is only a typical application of the Fock.

Optional # include <unistd. h> pid_t Fock (void); Return Value: 0 for the child process and-1 for the child process in the parent process --- fail -------------------------------------------------------------------

After the Fock function is called, two times are returned. The parent process returns the child process ID and the child process returns 0.

With the basic knowledge above, we can learn more about TCP and UDP interfaces.

1. TCP Interface

TCP interfaces use TCP to establish a connection. Three handshakes are required to establish a TCP connection. The basic process is that the server first sets up an interface and waits for client connection requests; when the client calls connect for an active connection request, the client TCP sends a SYN to notify the Server client of the initial serial number of the data sent in the connection; when the server receives this SYN, it also sends a SYN to the client, which contains the initial serial number of the data that the server will send in the same connection. Finally, the customer confirms the SYN sent by the server. So far, a TCP connection has been established.

The following uses an example to illustrate how the server and the customer are connected.

-------------------------------------------------------------------/* Client. C */# include <stdio. h> # include <stdlib. h> # include <errno. h> # include <string. h> # include <netdb. h> # include <sys/types. h> # include <netinet/in. h> # include <sys/socket. h> int main (INT argc, char * argv []) {int sockfd, numbytes; char Buf [100]; struct hostent * He; struct sockaddr_in their_addr; int I = 0; // convert the basic name and address to He = gethostbyname (ARG V [1]); // create a TCP set of interfaces if (sockfd = socket (af_inet, sock_stream, 0) =-1) {perror ("socket "); exit (1);} // initialize the struct, connect to the server's 2323 port their_addr.sin_family = af_inet; their_addr.sin_port = htons (2323); their_addr.sin_addr = *) he-> h_addr); bzero (& (their_addr.sin_zero), 8); // establish a connection with the server if (connect (sockfd, (struct sockaddr *) & their_addr, sizeof (struct sockaddr) =-1) {perror ("Connect"); exit (1) ;}// send the string "hell" to the server O! "If (send (sockfd," Hello! ", 6, 0) =-1) {perror (" send "); exit (1);} // If (numbytes = Recv (sockfd, buf, 100,0) =-1) {perror ("Recv"); exit (1);} Buf [numbytes] = ''; printf (" result: % s ", Buf); close (sockfd); Return 0;} ----------------------------------------------------------------/* server. C */# include <stdio. h> # include <stdlib. h> # include <errno. h> # include <string. h> # include <sys/types. h> # include <netinet/in. h> # include <sys/ Socket. h> # include <sys/Wait. h> main () {int sockfd, new_fd; struct sockaddr_in my_addr; struct sockaddr_in their_addr; int sin_size; // establish the TCP set interface if (sockfd = socket (af_inet, sock_stream, 0) =-1) {perror ("socket"); exit (1) ;}// initialize the struct and bind port 2323 my_addr.sin_family = af_inet; my_addr.sin_port = htons (2323); region = inaddr_any; bzero (& (my_addr.sin_zero), 8); // bind the set of interfaces if (BIND (sockfd, (struct sockaddr *) & my _ ADDR, sizeof (struct sockaddr) =-1) {perror ("bind"); exit (1) ;}// create a listener set interface if (Listen (sockfd, 10) =-1) {perror ("listen"); exit (1) ;}// wait for the connection while (1) {sin_size = sizeof (struct sockaddr_in ); perror ("server is run"); // If a connection is established, a new socket, if (new_fd = accept (sockfd, (struct sockaddr *) & their_addr, & sin_size) =-1) {perror ("accept"); exit (1) ;}// generate a sub-process to complete the session with the client, the parent process continues to listen to If (! Fork () {// read the information sent from the client if (numbytes = Recv (new_fd, buff, strlen (buff), 0) =-1) {perror ("Recv"); exit (1);} printf ("% s", buff ); // send the received information from the client back to the client if (send (new_fd, buff, strlen (buff), 0) =-1) perror ("send "); close (new_fd); exit (0);} Close (new_fd);} Close (sockfd );}------------------------------------------------------------------

Now let's compile these two programs:

root@linuxaid#gcc -o server server.croot@linuxaid#gcc -o client client.c

Then, run the server program on one computer, and then run the client on another terminal. The result is displayed. If you run the client program without running the server program, the prompt "Connect: connection refused ", which is the benefit of the TCP interface. If it is a UDP interface, there will be a delay to get an error message (This section describes the UDP interface later ).

Three handshakes are required to establish a TCP connection, and four subsections are required to disconnect a TCP connection. When an application process calls close (active) (either a server or a client), TCP at this end sends a fin, indicating that the data has been sent; the other end (passive end) sends a confirmation message. After all the application processes to be processed by the passive end are processed, a fin is sent to the active end and a set of interfaces is closed, after receiving the fin, the active end sends a confirmation message, so far the TCP connection is disconnected.

2. UDP APIs

The UDP interface is a connectionless and unreliable Datagram Protocol. Why is it used since it is not reliable? 1. When an application uses broadcast or multicast, it can only use UDP protocol. 2. It is fast because it is connectionless. Because UDP sets of interfaces are connectionless, if one party loses its datagram, the other party will wait infinitely. The solution is to set a timeout.

When writing a UDP set of interface programs, pay attention to the following points: When an interface is set up, the second parameter of the socket function should be sock_dgram, indicating that a UDP set of interfaces is set up; because UDP is not connected, the server does not need the listen or accept function. When the UDP interface calls the connect function, the kernel only records the IP address and port of the connection, and immediately return to the calling process. Because of this feature, UDP server programs can complete all customer requests without using the Fock function.

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.