Socket explanation
Socekt, also known as a ' socket ', is used to describe IP and address ports, which is a handle to a communication link, and an application typically makes a request to the network via a socket or answers a network request.
Sockets originate from UNIX, so they also follow the basic philosophy of "Everything is File", and for files, open/read/close mode of operation. socket is an implementation of this pattern, the socket is a special kind of file, some of the socket function is to do it (read/write Io, open, close).
The difference between the socket and file files:
- The file module is opened, read-write, and closed for the specified files.
- The socket module is open, read-write, and shutdown for the server and client sockets .
Socket Object
SK = Socket.socket (socket.af_inet,socket. sock_stream,0)
Parameter one: Address cluster
| Parameters |
Description |
| Socket.af_inet |
IPV4 (default) |
| Socket.af_inet6 |
IPv6 |
| Ocket.af_unix |
Can only be used for single UNIX system interprocess communication |
Parameter two: type
| Parameters |
Description |
| Socket. Sock_stream |
Streaming socket, for TCP (default) |
| Socket. Sock_dgram |
Datagram socket, for UDP |
| Socket. Sock_raw |
The original socket, the ordinary socket can not handle ICMP, IGMP and other network messages, and Sock_raw May, second, Sock_raw can also handle special IPV4 messages, in addition, using the original socket, you can use the IP_HDRINCL socket option by the user constructs the IP header. |
| Socket. Sock_rdm |
is a reliable form of UDP that guarantees the delivery of datagrams but does not guarantee the order. Sock_ram is used to provide low-level access to the original protocol, which is used when certain special operations are required, such as sending ICMP packets. Sock_ram is typically used only by advanced users or by programs that are run by administrators. |
| Socket. Sock_seqpacket |
Reliable, continuous packet service |
Socket class method
| Method |
Description |
| S.bind (Address) |
Binds a socket to an address. The format of address addresses depends on the address family. Under Af_inet, address is represented as a tuple (host,port). |
| Sk.listen (Backlog) |
Start listening for incoming connections. The backlog specifies the maximum number of connections that can be suspended before a connection is rejected. |
| Sk.setblocking (BOOL) |
Whether blocking (default true), if set to false, then the accept and recv when there is no data, the error. |
| Sk.accept () |
Accepts the connection and returns (Conn,address), where Conn is a new socket object that can be used to receive and send data. Address is the location of the connection client. |
| Sk.connect (Address) |
The socket that is connected to the address. Generally, address is in the form of a tuple (Hostname,port) and returns a socket.error error if there is an error in the connection. |
| SK.CONNECT_EX (Address) |
Ditto, but there will be a return value, the connection succeeds when the return 0, the connection fails when the return encoding, for example: 10061 |
| Sk.close () |
Close Socket Connection |
| SK.RECV (Bufsize[,flag]) |
Accepts the data for the socket. The data is returned as a string, and bufsize specifies the maximum quantity that can be received. Flag provides additional information about the message, which can usually be ignored. |
| Sk.recvfrom (Bufsize[.flag]) |
Similar to recv (), but the return value is (data,address). Where data is the string that contains the received information, address is the socket addressing that sent the data. |
| Sk.send (String[,flag]) |
Sends data from a string to a connected socket. The return value is the number of bytes to send, which may be less than the byte size of the string. That is, the specified content may not be sent all. |
| Sk.sendall (String[,flag]) |
Sends data from a string to a connected socket, but attempts to send all data before returning. Successful return none, Failure throws an exception. Internally, the send is called recursively, sending all the content. |
| Sk.sendto (string[,flag],address) |
Sends the data to the socket, address is a tuple in the form of (Ipaddr,port), specifying the remote address. The return value is the number of bytes sent. This function is mainly used for UDP protocol. |
| Sk.settimeout (Timeout) |
Sets the timeout period for the socket operation, and timeout is a floating-point number in seconds. A value of None indicates no over-time. |
| Sk.getpeername () |
Returns the remote address of the connection socket. The return value is typically a tuple (ipaddr,port). |
| Sk.getsockname () |
Returns the socket's own address. Typically a tuple (ipaddr,port) |
| Sk.fileno () |
File descriptor for sockets |
Socket Programming Ideas
- Create sockets, BIND sockets to local IP and ports
- Start listening for connections
- Enter the loop and continue to accept client connection requests
- Then receive the incoming data and send it to the other data
- When the transfer is complete, close the socket
- Create sockets to connect to the remote address
- Send data and receive data after connection
- When the transfer is complete, close the socket
Server side:
socketip_port = (‘127.0.0.1‘,9999)sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)sk.bind(ip_port)while True: data = sk.recv(1024) print(data.decode())
Client side:
socketip_port = (‘127.0.0.1‘,9999)sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)while True: inp = input(‘数据:‘).strip() if inp == ‘exit‘: break sk.sendto(bytes(inp,encoding=‘utf8‘),ip_port)sk.close()
Socket Sticky pack problem
SK.RECV (1024), the BufSize value is 1024, can only accept a maximum of 1024 bytes, then if the client sends the packet is particularly large, exceeding the value of the specified bufsize, more than the non-branch left in the kernel buffer, The next time you call recv, you will continue to read the remaining bytes. This is the so-called sticky bag problem, so how to solve it?
Similar to the HTTP protocol, we can:
- Tell the receiving data side before sending the byte size of the data I want to send
- A confirmation message is sent back to the data sender after receiving the data.
- After the data sender receives the confirmation message, the data is sent
- The data receiving end loops through the data until the data is accepted and the full packet is received
Client side:
ImportSocketip_port= (' 127.0.0.1 ',9999)s=Socket.Socket ()S.Connect (Ip_port)While True:send_data=input (' >>: '). Strip ()If send_data==' Exit ':BreakIf Len (send_data) = =0:ContinueS.Send (bytes (send_data,encoding=' UTF8 ')) ready_tag=S.Recv1024x768) Ready_tag=str (ready_tag,encoding=' UTF8 ')If Ready_tag.startswith (' ready '): msg_size=Int (ready_tag. Split (' | ') [-1]) print (msg_size) start_tag=' start ' S.Send (bytes (start_tag,encoding=' UTF8 ')) recv_size=0 Recv_msg=b"while Recv_size < Msg_size:recv_data=S.recv (1024x768) Recv_msg+=recv_data recv_ Size+=len (recv_data) print (str (recv_msg,encoding=' UTF8 '))S.Close ()
Server side:
ImportSocket,subprocessip_port= (' 127.0.0.1 ',9999)s=Socket.Socket ()S.Bind (Ip_port)S.Listen5)While True:conn,addr=S.Accept ()While True:try:recv_data=conn.Recv1024)If recv_data==0:Break p=subprocess. Popen (str (recv_data,encoding=' UTF8 '), shell=true,stdout=subprocess. PIPE) res=p.stdout.Read () if Len (res) = =0:send_data=' cmd ERROR ' send_data=bytes (send_data,encoding=' UTF8 ') else : Send_data=res ready_tag=' ready|%s '%len (SEND_DATA) Conn. Send (bytes (ready_tag,encoding=' UTF8 ')) feedback=conn. Recv (1024x768) feedback=str (feedback,encoding=' UTF8 ') if Feedback.startswith (' Start '): Conn. Send (Send_data) except Exception as ex: Break Conn. Close ()
Python's Socket Network programming