The Socket API is a standard API for practical application development in Web applications. Although the API is simple, 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 the easiest mistake for a novice developer to make. If you ignore the return state of a function, you may get lost when they fail or partially succeed. This, in turn, can spread errors, making it difficult to locate the source of the problem.
captures and checks each return state, rather than 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 send in nonblocking mode (by msg_dontwait Flag is enabled) under an attribute.
The Send API function has three types of possible return values:
· returns 0if the data is successfully queued to the transmission queue.
· If the queue fails, return 1(by using the The errno variable can understand the cause of the failure.
· if not all characters can be queued when the function is called, the final return value is the number of characters sent.
because of the non-blocking nature of the msg_dontwait variable of send, the function call sends out all the data, Some data or no data is sent back. 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, directories, 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, If the end of the file has been reached.
If a single socket is completed on a 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. The indication is the same as the file read - no extra data can be read by descriptor (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 this case, the sigpipe signal is received, or if 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 function to bind an address (an interface and a port) to an endpoint of a socket. You can use this function in server settings to limit the interfaces that may come with the connection. You can also use this function in client settings to limit the interfaces that should be used for connections that should be made available. bind inaddr_any
Bind  bind  return EaddrinuseTCP  socket status   Time_wait  2 after the socket is closed, Span style= "font-family:arial" >4  minutes. In   time_wait After the status exits, the socket is deleted and the address can be re-bound without problems.
wait for   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 reboot. Fortunately, there are ways to avoid   time_wait state. You can apply to sockets; so_reuseaddr socket options so that ports can be reused immediately.
Consider The example in Listing 3. Before binding the address, I call setsockopt with the SO_REUSEADDR option. To allow address reuse, I set the integer parameter (on) to 1 (otherwise, it 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 allow 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 shown 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 left peer layer completes the write operation of two sockets, 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. In other words, the message boundaries provided by the writer are reserved for the reader.
now look at the diagram 1  tcp , 100  200  TCP  TCP/IP  Either the sender or the receiver of the protocol stack. It is important to note that aggregations may not occur -- TCP 
For most developers, this trap can cause confusion. You want to obtain TCP Reliability and frame synchronization for UDP. Application layer developers are required to implement buffering and staging functions unless other transport protocols, such as streaming Transmission Control Protocol (STCP), are used instead.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Linux Socket Programming Considerations