Effective TCP/IP programming reading notes

Source: Internet
Author: User
Tags connection reset

TCP/IP Deep thinking

This is my reading effective TCP/IP programming reading notes and thinking, as well as doing some experiments. It is strongly recommended that the backend engineer have the time to read the book, some of the details are indeed we do not pay attention to, read the best to do some experiments to deepen understanding.

The meaning of fin

Sending fin to the end causes read () to return, but send () can still be sent, that is, the simple fin is actually equivalent to shutdown (SHUT_WR).

When the peer-to-peer application crashes (not close), this paragraph always calls send () and the peer returns the RST, at which time read () returns connection reset by peer.

When a peer-to-peer application crashes or a close connection, this section calls read () to return 0,
Calling Send () causes epipe (broken pipe) and the second send () to fail.

Peer host crashes

Recv () is permanently blocked because the host crashes, or the application shuts down, or the modern is shut down directly, causing the other party to accept Fin,rst, and so on. Workaround:

1. Turn on the keepalive mechanism, which expires by default (2+9*75/60) hours
2.RECV () timeout mechanism
3. Heartbeat, is actually sending send (), a period of time will detect the connection is broken

So_linger in-depth understanding

If the application performs an active shutdown and the TIME_WAIT state is finally maintained at 2MSL, the So_linger option forces the connection to close immediately, without taking the normal 4-step shutdown process.
Server

fromimport *s = socket(AF_INET,SOCK_STREAM)s.bind(("localhost",9123))s.listen(10)cc = s.accept()print#查看零时端口为47128

Client

fromimport *c = socket(AF_INET,SOCK_STREAM)c.connect(("localhost",9123))c.close()

Because the client actively shuts down, the client should be in the fin_wait2,server corresponding to the close_wait

[[email protected]10 -9 -22 -239  ~]# Netstat-an | grep 47128  TCP 1  Span class= "Hljs-number" >0  127.0 . 0.1 : 9123  127.0
     . 0.1 : 47128  close_wait tcp 0  0  127.0 . 0.1 : 47128  127.0 . 0.1 : 9123  fin_wait2  

Note Netstat to add n parameters, otherwise it will parse into the service name according to/etc/services.
When the server side calls Cc[0].close () again, Clinet will be in time_wait state at this point. We add a so_linger option to the client socket.

fromstruct import *c.setsockopt(SOL_SOCKET,SO_LINGER,pack("ii",1,0))

At this point we see that there is no corresponding state, that is, the state of the new type Fin_wait2, directly close, do not go normal four steps to close the connection process.

Of course, a strong application server should not interfere with the time_wait state, which is an important part of the TCP reliability mechanism.
The So_linger option has other effects, usually close () returns immediately when Close () is connected, even if the send buffer still has data to send. Of course, TCP will still try to send the data that is not sent out, but the application does not know whether to send the success, So_linger is to solve this problem.

struct linger{    int// on/off选项    int//逗留时间};

1.l_onoff for 0,linger not enabled, behavior and default close () are the same
2.l_onoff not 0, if L_linger non-0,close () is waiting for the data to be sent or the stay time timeout, if the stay time to, there is still no data sent, close () return Ewouldblock, if the linger is 0, the connection will be discarded, That's what we showed above.

Nagle algorithm and Delay ACK

The Nagle algorithm helps prevent tabloid flooding in the network, but interacting with delayed ACK may result in 200ms latency. BSD Implementation ACK delay 200MS,RFC rules can not be greater than 500ms, I do on the Linux experiment found are 40ms delay ack.

Close the Nagle algorithm

const  int  on = 1 ; Setsocket (S, ipproto_tcp, Tcp_nodelay, &on, Span class= "Hljs-keyword" >sizeof  (on));  
//from tornadotry:    1)exceptas e:    # Sometimes setsockopt will fail if the socket is closed    # at the wrong time.  This can happen with HTTPServer    # resetting the value to false between requests.    ifnotin (errno.EINVAL, errno.ECONNRESET):        raise

Coping methods:

1. Merge the write operation, using Writev ()
2. Multi-use buff, such as go in Bufio. Reader,bufio. Writer

Non-blocking Connect

The non-blocking connect () immediately returns to Einprogress, and if the connection succeeds the socket is immediately writable, how do you check if the connection is successful?

=......// 返回0,成功连接if!=0&&!= EINPROGRESS) {    close(sock);}

You can use getsockopt to check for errors and, of course, to wait for the socket state to change before

interror;socklen_t len = sizeof(error);  int code = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len);  if0error) {  //返回值小于0或error不等于0说明连接错误    close(s);    return SOCKET_ERROR;}

Use Python to simulate the following:

ImportSocketImportSelectImport errnos=Socket.Socket(Socket. Af_inet,Socket. SOCK_STREAM)s. setblocking (False) Try:s.Connect(("www.google.com", the)) exceptSocket. Error as E:ifE.errno = = errno. Einprogress:Print("INprocess")Else: Raiser,w,x=Select.Select([s],[s],[s]) Err =s.getsockopt(Socket. Sol_socket,Socket. So_error)ifErr! =0:Print("Error", Errno.errorcode[err])s.Close()Else:Print("Connect OK")

Obviously, do not turn over the wall www.google.com temporarily connected, error message

INprocess(‘error‘‘ETIMEDOUT‘)
Understanding UDP Connect

Benefits of using UDP Connect:

1. Using connect () to improve performance, BSD implementation of SendTo () is the special column of Connect, the kernel temporarily let the socket with the destination address, send the packet, and then the connection is unblocked.
2. Asynchronous errors can be accepted, because UDP is stateless, the data is sent out, the system will forget, so even if the ICMP message is returned, do not know which application sent the packet, using connect will record the corresponding information.

s=socket(AF_INET,SOCK_DGRAM)s.connect(("localhost",9999))s.send("1111")s.recv111] Connection refused

After send (), the ICMP message report is unreachable, again recv or Recvfrom will error.

Buffer size

The send buffer is set to 3 times times the size of the MSS, which effectively reduces the interaction problems caused by the Nagle algorithm and delayed ack.
Linux default send buffer is 4K, Ethernet MSS is 1460, still very reasonable.

The Send buffer size is greater than or equal to the recipient's accept buffer, because the sender can only receive an ACK to release the sent data, so the send buffer is easily full and no new data is sent, resulting in a 40ms delay ack.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Effective TCP/IP programming reading notes

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.