Python3 socket module and socket communication flow

Socket classification

This classification is a convenient division of sockets that are used differently, and sockets that are used in this way are referred to by these names. That is. However, it is clear that the listening socket is in a different state (ie Passive mode) because it is certain that it cannot ** send a connection request ** (Error: Transport endpoint is already connected).

Server side Client side Explanation
listening socket listen()Becomes this socket by executing. ---- You are listening to a specific port. Send connection requests to other listening sockets(connect()To do)It is not possible. It is also said that the socket is in passive mode or is a passive socket.
connected socket accept()This socket is passed in the return value of the function. connect()Is executed, and it becomes this socket by being accepted on the server side. Connected socket. sent,You can do recv etc.
All sockets other than the above listen()Socket before running connect()Socket before being accepted by the server side listen()Also connect()Is also possible. listen listen()In the case of bind()Is necessary.

Flow of socket API functions

One line is at the same time (not a physics term). There are some that are not one line, but almost one line, but they are not one line for the sake of clarity. Regarding the state, I checked the packet with Wireshark and guessed it, so there may be something wrong. There are various methods for cutting, so this is just an example. And, strictly speaking, the functions that disconnect the connection are shutdown and close. It seems that the name shutdown is more realistic and the name close is destroy. (https://stackoverflow.com/questions/409783/socket-shutdown-vs-socket-close)

The socket descriptor in the table, On the server side, listening_sock = socket.socket (), connected_sock = listening_sock.accept (). However, the socket referenced by listening_sock goes into the listening state afterlistening (). The reason why it is set to listening_sock at the time of socket creation is that it is clear that after that,listen ()is performed to become a listening socket. On the client side, sock = socket.socket ().

From socket generation to 3 WAY handshake.

Server-side functions Explanation Server side state Client-side function Explanation Client side status
socket.socket() Generation of sockets for listening. CLOSED socket.socket() Generating a socket for connection. CLOSED
listening_sock.bind() Naming the socket. CLOSED ---- ---- CLOSED
listening_sock.listen() Here, the socket actually becomes a listening socket and starts listening. The OS accepts the connection request. LISTENING ---- ---- CLOSED
---- LISTENING sock.connect() Connect the socket directly to the specified address. SYN SENT
---- SYN RECV ---- SYN SENT
---- ESTABLISHED ---- ESTABLISHED

From 3 WAY handshake to before cutting.

Server-side functions Explanation Server side state Client-side function Explanation Client side status
---- ---- ESTABLISHED ---- ---- ESTABLISHED
listening_sock.accept() Accept the connection request. ---- ----
---- ---- sock.sendall() Send a message to the server.
connected_sock.recv() Receive client-side messages. ---- ----
connected_sock.sendall() Send back the message. ---- ----
---- ---- sock.recv() Receive server-side messages.

Disconnection (4 WAY handshake)

Server-side functions Explanation Server side state Client-side function Explanation Client side status
---- ---- ESTABLISHED ---- ---- ESTABLISHED
connected_sock.close() Terminate the connection. Any processing below this for sock(recv, send)Can't do it either. FIN-WAIT-1 ---- ---- ESTABLISHED
---- FIN-WAIT-2 ---- ---- CLOSE-WAIT
---- FIN-WAIT-2 sock.close() Terminate the connection. Any processing below this for sock(recv, send)Can't do it either. LAST-ACK
---- TIME-WAIT ---- ???????
---- ---- CLOSED ---- ---- CLOSED

Details while looking at the code.

Server side

socket()

First, create a socket (which I intend to use only to accept connection requests, that is, a listening socket).

The file descriptor that represents (references) the created socket is returned.

>>> listening_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

>>> listening_sock
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>

AF_INET indicates that the communication uses IPv4, and SOCK_STREAM indicates that the socket is a socket for connection-type communication (stream-type communication) such as TCP. (* And provide full-duplex communication)

You can see that the IP address or port number of <... laddr = ...> is all 0, set this next.

bind()

Then assign an address to that socket descriptor (listening_sock).

>>> listening_sock.bind(('127.0.0.1', 8000))

>>> listening_sock
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8000)>

You can see that (ip address, port number) is set in <... laddr = ...>.

listen()

The generated socket starts listening at this point. Originally, at this point, it is only listening and not accepting, but the OS accepts the client's connection request on behalf of the application (that is, connects instead) and adds it to the application's acceptance queue (queue) To go. The OS can accept connection requests on behalf of the application up to the number given by the backlog argument. Once the connection is passed to the application (that is, the application accepts it), there is one free space in the accept queue. Then, when the connection request is accepted, a new connection is created between the client-side socket and the new listening socket-independent connected socket, the listening socket reboots for the next connection request, and again on the same port. Listen.

>>> listening_sock.listen(5)

In the case of this code, backlog is 5, so the OS can accept connection requests from 5 client-side sockets and put them on the acceptance queue. Any further connection request will result in an error.

accept()

When accept () is executed, the descriptor of the connected socket of the connection at the top of the queue accepts the incoming connection request if the OS accepts the connection request instead, otherwise it accepts the descriptor of the connected socket of that connection. return.

>>> connected_sock, client_address = listening_sock.accept()

In the above case, it accepts the connection request that comes to listening_sock, creates a new socket called connected_sock, and establishes a connection between that socket and the socket on the client side. (Neither listening_sock nor connected_sock is actually the socket itself) [Note]

I honestly don't know about this area. When [SYN] comes to the listening socket, will it send back [SYN, ACK] from the new socket to establish the connection? Or is there a concept of sockets at the level of the 3way handshake? In the first place, socket is an API that allows programmers to create communication programs optimized for the application without knowing the complicated parts of TCP (window control, flow control, retransmission control, etc.) and the parts below IP in detail. At the time of the 3way handshake, it may be that only the communication destination is determined by the address on the client side.

Client side

socket()

First, create a socket. Then the file descriptor that represents (references) the created socket is returned.

>>> listening_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

>>> listening_sock
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('0.0.0.0', 0)>

connect()

Here, the connection request is actually sent to the listening socket (listening to the specified port) of the server.

>>> sock.connect(server_address)

Server client both sides

sendall()

Send data.

recv()

Receive data.

close()

Release resources related to connection. (* Actually, you need to do shutdown () before this. Https://docs.python.org/ja/3/howto/sockets.html#disconnecting)

reference

  1. http://research.nii.ac.jp/%7Eichiro/syspro98/server.html
  2. https://blog.stephencleary.com/2009/05/using-socket-as-server-listening-socket.html
  3. https://web.mit.edu/6.005/www/fa15/classes/21-sockets-networking/#network_sockets
  4. https://www.ibm.com/support/knowledgecenter/ssw_ibm_i_71/rzab6/howdosockets.htm
  5. https://docs.microsoft.com/en-us/windows/win32/api/winsock2/
  6. https://docs.python.org/ja/3/library/socket.html
  7. https://docs.python.org/ja/3/howto/sockets.html
  8. https://ja.wikipedia.org/wiki/%E3%82%BD%E3%82%B1%E3%83%83%E3%83%88_(BSD)
  9. https://linux.die.net/man/2/
  10. http://www.7key.jp/nw/tcpip/tcp/tcp2.html

Recommended Posts

Python3 socket module and socket communication flow
Socket communication and multi-thread processing by Python
Socket communication by C language and Python
Socket communication with Python
Python debug and test module
Socket communication with Python LEGO Mindstorms
Cooperation between python module and API
Implementation module "deque" in queue and Python
Socket communication using socketserver with python now
Module import and exception handling in python
Python module import
Communication and networking
Python collections module
Python development flow using Poetry, Git and Docker
Python Socket communication sample / simple data throwing tool
[Python] Class type and usage of datetime module
Serial communication with Python
[python] Compress and decompress
Serial communication with python
Communication processing by Python
Batch design and python
Python iterators and generators
python original module import
Python packages and modules
Vue-Cli and Python integration
Control other programs from Python (communication between Python and exe)
Ruby, Python and map
__future__ module and future_builtins module
Communication between uWSGI and Nginx using Unix Domain Socket
Send data from Python to Processing via socket communication
python input and output
Python basics: Socket, Dnspython
WiringPi-SPI communication using Python
(Beginner) SSL socket communication
HTTP communication with Python
Interprocess communication between Ruby and Python (POSIX message queue)
Python3, venv and Ansible
Python asyncio and ContextVar
Sample of getting module name and class name in Python
HTTP server and HTTP client using Socket (+ web browser) --Python3
[Python of Hikari-] Chapter 08-03 Module (Import and use of standard library)
Python module num2words Difference in behavior between English and Russian
Serial communication control with python and I2C communication (using USBGPIO8 device)
Serial communication control with python and SPI communication (using USBGPIO8 device)
Module summary that automates and assists WebDriver installation with Python
TCP communication using Socket module-Python3
Encryption and decryption with Python
Sort Python module imports alphabetically
How Python module import works
3-3, Python strings and character codes
Python 2 series and 3 series (Anaconda edition)
Python and hardware-Using RS232C with Python-
Python on Ruby and angry Ruby on Python
Python indentation and string format
Python real division (/) and integer division (//)
Learning flow for Python beginners
[Python] ModuleNotFoundError: No module named'urlparse'
Å (Ongustromu) and NFC @ Python
Automatic update of Python module
Understand Python packages and modules
# 2 [python3] Separation and comment out