Linux Socket Programming Considerations

Source: Internet
Author: User
Tags closure what interface

The Socket API is a standard API for practical application development in Web applications. Although the API is simple. However, novice developers may experience some common problems. This article identifies some of the most common pitfalls and shows you how to avoid them.

Hidden trouble 1. Ignore return status

The first pitfall is obvious, but it's a mistake for the easiest developer to make.

Suppose you ignore the return state of a function, and when they fail or partially succeed, you may be lost.

Turn. This may propagate errors. Make it difficult to locate the source of the problem.

captures and checks each return status. Instead of ignoring them. Consider The example shown in Listing 1, a socket send function.

Listing1.IgnoreAPIfunction return Status

int status, sock, mode;/* Create a new stream (TCP) Socket */sock = socket (af_inet, sock_stream, 0), .... Status = Send (so CK, buffer, Buflen, msg_dontwait); if (status = =-1) {/  * Send failed *  /printf ("Send failed:%s\n", strerror (err NO));} else {/  * Send succeeded--or did it? */}


Listing 1 explores a function fragment that completes the socket send operation (sending data through a socket). The error state of the function is captured and tested, but this example ignores the send in the non-clogging mode (by msg_dontwait Flag is enabled) under an attribute.

The Send API function has three types of possible return values:

·  assume that the data is successfully queued to the transmission queue. Then 0is returned.

·  suppose the queue fails. Returns 1(by using The errno variable to understand the cause of the failure).

·  assuming that not all characters can be queued when the function is called, the last return value is the number of characters sent.

because of the non-clogging nature of the msg_dontwait variable of send, the function call sends the data in the complete part, Some data or no data sent back after no matter what. Ignoring the return status here will result in incomplete sending and subsequent data loss.

Hidden Trouble 2. Peer socket closure

the funny side of UNIX is that you can almost think of anything as a file. The files themselves, folders, pipelines, devices, and sockets are treated as files.

This is a novel abstraction, meaning that a complete set of APIs can be used on a wide range of device types.

consider The Read API function, which reads a certain number of bytes from a file.

The Read function returns the number of bytes read (up to the maximum value you specify), or 1, which indicates an error, or 0, assuming that the end of the file has been reached.

let's say one of the sockets is finished. the read operation is given a return value of 0 , which indicates that the peer layer on the remote socket side called the close API method. This instruction is the same as a file read - No excess data can be read by descriptive descriptors (see listing 2).

Listing2. Proper handlingRead APIreturn value of the function

int sock, Status;sock = socket (af_inet, sock_stream, 0), .... Status = Read (sock, buffer, buflen); if (Status > 0) {
   /* Data read from the socket */} else if (status = =-1) {/  * Error, check errno, take action ... */} else if (status = = 0) {  /* Peer closed the socket, finish the close *  /close (sock);  /* Further processing ... */}


Similarly, you can use the Write API function to probe the closure of a peer socket.

In such a case, receiving a sigpipe Signal, or assuming that the signal is blocked,the write function returns 1 and sets errno for epipe.

Hidden Trouble 3. Address usage error (eaddrinuse)

You can use bind API functions to bind an address (an interface and a port) to a socket endpoint. The ability to use this function in the server settings to limit the interfaces that may come with the connection. You can also use this function in the client settings to limit the interfaces that should be used for connections that should be made available. The most common use of BIND is to associate the port number with the server and use the wildcard address (inaddr_any), which agrees that no matter what interface is used for incoming connections.

The common problem with BIND is trying to bind a port that is already in use.

The trap is that there may not be an active socket, but it is still forbidden to bind port (bind returns Eaddrinuse). It is caused by the TCP socket State time_wait . The status is approximately 2 to 4 minutes after the socket is closed .

After the time_wait state exits. The socket is removed, and the address talent is bound again without problems.

wait Time_wait end may be annoying, especially if you are developing a socket server, you need to stop the server to make some changes and then restart. Fortunately, there are ways to avoid the time_wait state. The ability to apply the SO_REUSEADDR socket option to sockets so that the port can be reused immediately.

Consider the sample in Listing 3. Before binding the address, I call setsockopt with the SO_REUSEADDR option.

In order to agree to the reuse of addresses, I set integer parameters (on) to 1 (otherwise.) Can be set to 0 to prohibit address reuse).

Listing3. Useso_reuseaddrsocket option avoids address usage errors

int sock, ret, on;struct sockaddr_in servaddr;/* Create A new stream (TCP) Socket */sock = socket (af_inet, sock_stream, 0 ):/* Enable address reuse */on = 1;ret = setsockopt (sock, Sol_socket, so_reuseaddr, &on, sizeof (on));/* Allow Conne Ctions to port 8080 from any available interface */memset (&servaddr, 0, sizeof (SERVADDR)); servaddr.sin_family = Af_i NET;SERVADDR.SIN_ADDR.S_ADDR = htonl (inaddr_any); servaddr.sin_port = Htons (45000);/* Bind to the address (INTERFACE/PO RT) */ret = Bind (sock, (struct sockaddr *) &servaddr, sizeof (SERVADDR));


in the application of After the so_reuseaddr option,the bind API function will agree to the immediate reuse of the address.

Hidden Trouble 4. Frame synchronization Assumptions in TCP

TCP does not provide frame synchronization, which makes it perfect for byte-stream-oriented protocols. This is an important difference between TCP and UDP(userDatagram Protocol, Subscriber Datagram Protocol). UDP is a message-oriented protocol that preserves message boundaries between senders and receivers. TCP is a stream-oriented protocol that assumes that the data being communicated is unstructured, as seen in 1.

Figure1. UDPframe synchronization capability and lack of frame synchronization.TCP

The upper part of Figure 1 illustrates a UDP client and server. The peer layer on the left completes two sockets of write operations, each of the four bytes.

The UDP layer of the protocol stack tracks the number of writes and ensures that when the receiver on the right gets the data through the socket, it arrives in the same number of bytes. Other words. The message boundaries provided by the writer are reserved for the reader.

Now, look at the bottom of Figure 1. It demonstrates the same granularity of write operations for the TCP layer. Two separate write operations (each of the four bytes) are written to the stream socket.

But in this case, the reader of the stream socket gets a byte. The TCP layer of the protocol stack aggregates two write operations. Such aggregations can occur on either side of the sender or receiver of the TCP/IP protocol stack.

It is important to note that aggregations may not occur --tcp only guarantees the orderly delivery of data.

For most developers, this trap can cause confusion.

You want to obtain TCP Reliability and frame synchronization for UDP. Unless you switch to other transport protocols, such as streaming Transmission Control Protocol (stcp), Application layer developers are required to implement buffering and staging functions.

Linux Socket Programming Considerations

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.