Python Development Basics----Socket Socket Basics 2

Source: Internet
Author: User

UDP-based sockets

Non-connected unreliable data transmission, can be no server side, but no server side, the data sent will be directly discarded, and can not reach the server side

1 #客户端2 Import Socket3 ip_port= (' 127.0.0.1 ', 8080) 4 bufsize=10245 sock_client=socket.socket (socket.af_inet,socket. SOCK_DGRAM)    #SOCK_DGRAM就是UDP6 while True:7     msg=input (' >> '). Strip () 8     if not msg:continue9     Sock_client.sendto (Msg.encode (' Utf-8 '), Ip_port)    #UDP用的是sendto发送数据

UDP Service side + client

1 #服务端 2 Import Socket 3 ip_port= (' 127.0.0.1 ', 8080) 4 bufsize=1024 5 sock_server=socket.socket (socket.af_inet,socket. SOCK_DGRAM) 6 Sock_server.bind (Ip_port) 7 #对比TCP, missing listen listening address, missing code for accept waiting for connection 8 while True:9     Msg,addr=sock_ Server.recvfrom (BUFSIZE)    #UDP接收数据使用recvfrom接收10     print (' recv: ', msg,addr)     sock_server.sendto ( Msg.upper (), addr) #客户端14 import socket15 ip_port= (' 127.0.0.1 ', 8080) bufsize=102417 Sock_client=socket.socket ( Socket.af_inet,socket. SOCK_DGRAM) and true:19     msg=input (' >> '). Strip () if not     msg:continue21     sock_client.sendto ( Msg.encode (' Utf-8 '), Ip_port)     * Back_msg,addr=sock_client.recvfrom (BUFSIZE)    #一般UDP用于广播, will not receive data, if there is no server, Error in enabling the line code     # Print (Back_msg.decode (' Utf-8 '), addr)

Because UDP is non-connected (in fact there is a link, otherwise through what to pass data to fetch data), you can use multiple clients to connect the server side, but this is not concurrent access.

Attention:

1. Messages are sent to the sending buffer on their own side, and the received messages are received from the buffers in their own

Tcp:send Send Message, recv receive message

Udp:sendto Send Message, recvfrom receive message

2. TCP is based on data flow, and UDP is datagram-based:

Send (Bytes_data): sends the data stream, the data stream Bytes_data if is empty, own this part of the buffer also is empty, the operating system does not control the TCP protocol to send the empty packet

Sendinto (Bytes_data,ip_port): Send a datagram, Bytes_data is empty, and ip_port, all even send empty bytes_data, the datagram is not empty, their own buffer to receive the contents of the end, The operating system will control the UDP protocol packet.

3.1 TCP protocol

(1) If the data in the message buffer is empty, then the recv will be blocked (blocking is simple, is waiting to receive)

(2) Only the TCP protocol client send an empty data is really empty data, the client even if there are infinite send empty, also with no one.

(3) TCP link-based communication

    • Based on the link, the listen is required, specifying the size of the half-connection pool
    • Based on the link, the server must run first, and then the client initiates the link request
    • For Mac Systems: If one end of the link is broken, the other end of the link is also finished recv will not block, received is empty (workaround is: The service side after receiving the message plus if judgment, the empty message will break off the communication loop)
    • For Windows/linux Systems: If one end of the link is broken, then the other end of the link is also finished recv will not be blocked, received is empty (workaround is: server-side communication loop with exception handling, catch the exception after the break off the communication loop)

3.2 UDP protocol

(1) If the data in the message buffer is "empty", Recvfrom will also block

(2) Only the UDP protocol client sendinto an empty data is not really empty data (including: empty data + address information, the resulting report will still not be empty), so as long as the client has a sendinto (whether or not to send empty data, is not really empty data), The server can recvfrom to the data.

(3) UDP no link

    • No links, so no listen, no more connection pool
    • No link, UDP sendinto do not have a running server, you can kept the message, but the data is lost
    • Recvfrom the data received is less than the data sent by Sendinto, the data is lost directly on Mac and Linux system, and it is sent on the Windows system more direct error than received
    • Only sendinto send data without recvfrom data, data loss

Sticky bag

Do something about the client code of SSH yesterday.

service-Side fixed code
1 #客户端动手脚 2 Import Socket 3 Ssh_client=socket.socket (socket.af_inet,socket. SOCK_STREAM) 4 Ssh_client.connect ((' 127.0.0.1 ', 8080)) 5 while True: #通讯循环 6     cmd=input (' >>: '). Strip () 7     If not cmd:continue 8     ssh_client.send (Cmd.encode (' Utf-8 ')) 9     cmd_res = SSH_CLIENT.RECV (+)    #动手脚位置, Change the size of data received to 100 bytes (     cmd_res.decode (' GBK ')) #windows11     # Print (Cmd_res.decode (' Utf-8 ')) #linux12 Ssh_ Client.close ()

After running the server, perform a client-side test:

1 >>: Dir 2  the volume in drive C is not labeled. 3  Volume serial number is 5e42-f448 4  5  C:\Users\Mr.chai\Desktop\PythonProject\ note 6 >>: pwd 7 2017.7.10\ socket _test Directory 8  9 2017/07/11  16:58    <DIR>          2017/07/11  16:58    <DIR>   >>: pwd12        .. 2017/07/10  11:04                 0 __init__.py14 2017/07/11  16:58               711 customer >>: Pwd16 end. Py17 2017/07/11  16:03             1,992 server. Py18                3 files          2,703 bytes  >>: pwd21               

Before the contrast does not move hands and feet:

1 >>: Dir 2  the volume in drive C is not labeled. 3  Volume serial number is 5e42-f448 4  5  C:\Users\Mr.chai\Desktop\PythonProject\ Note \2017.7.10\ Socket _test Directory 6  7 2017/07 /11  17:02    <DIR>          8 2017/07/11  17:02    <DIR>          : 9 2017/07/10  11:04                 0 _ _init__.py10 2017/07/11  17:02               712 client. Py11 2017/07/11  16:03             1,992 server. Py12                3 Files          2,704 bytes 13                

What happened?

What happened? The reason is this way.

The first is the principle of socket data transfer and data reception:

principle

Sticky packets will only appear in TCP.

UDP prompts you under Windows:

OSError: [Winerror 10040] A message sent on a datagram socket is larger than the internal message buffer or some other network limit, or the buffer used by the user to receive datagrams is smaller than the datagram

In the case of Linux, there will be data loss:

>>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA (' 192.168.1.10 ', 8080) >>

The problem is the receiver, this is because the receiver does not know the boundary between the returned messages, do not know how many bytes of data extracted at a time caused by the first DIR returns the message is much larger than 100 bytes, and understand the hands and feet can only take 100 bytes from the cache at a time, The data that was not taken out of the cache will continue to be taken again.

Case of Sticky pack:

The sending side need to wait for the buffer full to send out, resulting in sticky packets (send data time interval is very short, the data is small, to join together to produce sticky packets)

The receiver does not receive the buffer in time packets, resulting in multiple packets received (the client sent a piece of data, the server only received a small portion of the service end of the next time to collect the last data from the buffer, resulting in sticky packets)

Send (Byte stream) and recv (1024) and Sendall

Lowb method for solving sticky packets

The root of the sticky packet is that the receiver does not know the length of the stream to be transmitted by the sender, then the receiver will send the total size of the byte stream to let the receiver know, and then receive a dead loop to receive all the data

Service side

 1 Import Socket 2 Import subprocess 3 ip_addr= (' 127.0.0.1 ', 8088) 4 bufsize=1024 5 S_server=socket.socket (socket.af_inet,s Ocket. SOCK_STREAM) 6 s_server.setsockopt (socket. Sol_socket,socket. so_reuseaddr,1) 7 S_server.bind (IP_ADDR) 8 S_server.listen (5) 9 print (' Run server ... ') ten while True:12 Conn,addr=s_             Server.accept () Print (' Client address: ', addr) and true:15 try:16 client_res=conn.recv (BUFSIZE) 17 If Len (Client_res.decode (' utf-8 ')) = = = 0:continue18 res=subprocess. Popen (Client_res.decode (' Utf-8 '), shell=true,20 stdout =subprocess. Pipe,21 stderr=subprocess.   PIPE) Stdout=res.stdout.read () Stderr=res.stderr.read () Std_bytes=stdout+stderr #标准输出和标准错误组合25 Std_size=len (std_bytes) #计算总长度26 conn.send (str (std_size). Encode (' Utf-8 ')) #将 The total length is sent to the client, and the client receives the message returning a status of STATUS=CONN.RECV (BUFSIZE). Decode (' Utf-8 ') #将返回来的状态赋值28 if status: #如果该状态成立, then start sending all data conn.s End (std_bytes) except exception:31 break32 conn.close () s_server.close ()

Client

1 Import Socket 2 ip_addr= (' 127.0.0.1 ', 8088) 3 bufsize=100 4 S_client=socket.socket (socket.af_inet,socket. SOCK_STREAM) 5 S_client.connect (IP_ADDR) 6 while True:7     cmd=input (' >> '). Strip () 8     if not cmd:continue 9< C4/>s_client.send (Cmd.encode (' Utf-8 ')) ten     Std_size=int (S_CLIENT.RECV (BUFSIZE). Decode (' Utf-8 '))    # Converts the total length of the received data into a number of     s_client.send (' True '. Encode (' Utf-8 '))   #返回给服务器端一个状态True13     res=b '     get_size= 015     while get_size < std_size:16         if (std_size-get_size) <:   #如果总长度比下载的长度小于定义的100, then take the minimum value of the data, Otherwise press 100 to value             res+=s_client.recv (std_size-get_size)         else:19             res+=s_client.recv (BUFSIZE)         Get_size+=bufsize   #每取一次值加100, the last value must be greater than the total length of     print (Res.decode (' GBK ')) S_client.close ()

Solve the high-up method of sticky pack-Custom Data header

The method is based on the improvement of the above method, that is, before transmitting data, a fixed-length data header is set on the server, which encapsulates a series of information about the data, such as the total length of the data, or the user information, time information and so on, which the client obtains the entire data, Take the fixed length data head to read the information, receive the data according to the head information

Python Development Basics----Socket Socket Basics 2

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.