) Five risks in Linux socket programming

Source: Internet
Author: User

This articleArticleIt mainly solves the problem of BIND failure when I restart the service: set socket optionsSo_reuseaddr ~

Reprinted from: http://www.ibm.com/developerworks/cn/linux/l-sockpit/ really good entry.

Five risks in Linux socket programming

Introduced for the first time in 4.2 bsd unix, The Sockets API is now a standard feature of any operating system. In fact, it is difficult to find a modern language that does not support sockets APIs. This API is quite simple, but new developers still encounter some common risks.

This article identifies the risks and shows you how to avoid them.

Hazard 1. Ignore returned status

The first hidden danger is obvious, but it is the easiest mistake for new developers. If you ignore the return status of the function, you may be lost when they fail or are partially successful. In turn, this may spread errors, making it difficult to locate the source of the problem.

Capture and check each returned status, rather than ignoring them. Consider the example shown in Listing 1: A socketSendFunction.

Listing 1. Ignore the status returned by the API Function
Int status, Sock, mode;/* Create a new stream (TCP) socket */sock =Socket(Af_inet, sock_stream, 0);... status =Send(Sock, buffer, buflen, msg_dontwait); If (status =-1) {/* Send failed */printf ("Send failed: % s \ n ", strerror (errno);} else {/* Send succeeded -- or did it? */}

Listing 1 explores a function snippet that completes socketSendOperation (send data through socket ). Function error status is captured and tested, but this example ignoresSendIn the non-blocking modeMsg_dontwaitFeature.

SendThere are three possible return values for API functions:

    • If the data is successfully discharged to the transmission queue, 0 is returned.
    • If the queue fails,-1 is returned.ErrnoVariable ).
    • If not all characters can be queued during function calling, the final return value is the number of characters sent.

BecauseSendOfMsg_dontwaitThe variable is non-blocking. function calls return after all data is sent, some data, or no data is sent. Ignoring the returned status will lead to incomplete sending and subsequent data loss.

Back to Top

Hidden Danger 2. Equivalent socket Closure

One interesting aspect of UNIX is that you can regard almost everything as a file. Files, directories, pipelines, devices, and socketsComposition. This is a novel abstraction, meaning that a complete set of APIs can be used on a wide range of device types.

ConsiderationsReadAPI function, which reads a certain number of bytes from a file.ReadThe number of bytes read by the function (the maximum value you specify); or-1 indicates an error; or 0, if it has reached the end of the file.

If you completeReadOperation and obtain a return value of 0, which indicates that the Peer layer of the remote socket has calledCloseAPI method. This indicator is the same as reading a file-No redundant data can be read through the descriptor (see Listing 2 ).

List 2. Properly process the returned values of read API functions

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 useWriteAPI function to detect the closure of a peering socket. In this caseSigpipeSignal, or if the signal is blocked,WriteThe function returns-1 and setsErrnoIsEpipe.

Back to Top

Hidden Danger 3. Address usage error (eaddrinuse)

You can useBindAPI function to bind an address (an interface and a port) to a socket endpoint. You can use this function in server settings to restrict the interfaces that may be connected. You can also use this function in client settings to restrict the interfaces that should be used for outgoing connections.BindThe most common usage is to associate the port number with the server and use the wildcard address (Inaddr_any), Which allows any interface to be used for the incoming connection.

BindA common problem is trying to bind a port that is already in use. This trap may not have active sockets, but it is still prohibited to bind the port (BindReturnEaddrinuseBy the TCP socket status.Time_waitCause. This status is retained for about 2 to 4 minutes after the socket is disabled. InTime_waitAfter the status exits, the socket is deleted so that the address can be rebound.

WaitTime_waitEnding may be annoying, especially if you are developing a socket server, you need to stop the server and make some changes and restart it. Fortunately, there are ways to avoidTime_waitStatus. Can be used for socket applicationsSo_reuseaddrSocket options, so that the port can be reused immediately.

Consider the example in listing 3. Before binding an addressSo_reuseaddrOption callSetsockopt. To allow address reuse, I set the integer parameter (On) Is 1 (otherwise, it can be set to 0 to prohibit address reuse ).

Listing 3. Use the so_reuseaddr socket option to avoid 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 connections to port 8080 from any available interface */memset (& servaddr, 0, sizeof (servaddr); servaddr. sin_family = af_inet; servaddr. sin_addr.s_addr =Htonl(Inaddr_any); servaddr. sin_port =Htons(45000);/* bind to the address (interface/port) */ret =Bind(Sock, (struct sockaddr *) & servaddr, sizeof (servaddr ));

AppliedSo_reuseaddrOption,BindThe API function allows immediate address reuse.

Back to Top

Hidden Danger 4. Send structured data

Socket is a perfect tool for sending unstructured binary byte streams or ASCII data streams (such as HTTP pages over HTTP, or emails over SMTP. However, if you try to send binary data on a socket, it will become more complicated.

For example, if you want to send an integer, are you sure that the recipient will interpret the integer in the same way? Applications running on the same architectureProgramThis type
The data is interpreted in the same way. However, if a client running on a high-priority IBM PowerPC sends a 32-bit integer to a low-priority intel
X86, what will happen? The Byte arrangement will cause an incorrect explanation.

Is the byte exchange still not?

EndiannessIt refers to the order of memory bytes.Big endian)Sort by maximum valid bytes, howeverLow priority (little endian)Sort by the lowest valid bytes.

High-priority architecture (such as PowerPC), low-priority architecture (such as Intel Pentium
Series, the network byte order is high priority) has an advantage. This means that for high-priority machines, controlling data within TCP/IP is naturally ordered. Low-priority architecture requires byte switching --
This is a slight performance weakness for network applications.

What if I send a C structure through a socket? In this case, it will also be difficult, because not all compilers arrange elements of a structure in the same way. The structure may also be compressed to minimize the waste of space, which further places elements in the structure.

Fortunately, there is a solution to this problem, which can ensure the consistent interpretation of data at both ends. In the past, Remote Procedure
Call, RPC) Kit provides so-called external data representation (XDR ). XDR
Define a standard representation for data to support the development of communications between heterogeneous network applications.

Now there are two new protocols that provide similar functions. Extensible Markup Language/Remote Procedure Call (XML/RPC)
. Data and Metadata are encoded in XML and transmitted as strings. The host architecture separates values from their physical representation. Soap follow
XML-RPC, with better features and functions to expand its thinking. For more information about each protocol, see the references section.

Back to Top

Hidden Danger 5.frame synchronization assumption in TCP

TCP does not provide frame synchronization, which makes it perfect for byte stream-oriented protocols. This is
Protocol, User Datagram Protocol) is an important difference. UDP is a message-oriented protocol that retains the message boundary between the sender and receiver. TCP
Is a stream-oriented protocol. It assumes that the data being communicated is unstructured, as shown in 1.

Figure 1.udp Frame Synchronization capability and lack of TCP

Let's look at the original text later .. There are still images

 

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.