Network Communications
Purpose of using the network
Link multiple parties together for data transmission;
Network programming is to allow software on different computers to transfer data, that is, inter-process communication.
ip address
The concept and function of ip address
What is the IP address: some numbers like 192.168.1.1;
ip address: used to identify the only computer in the computer, such as 192.168.1.1; in the local area network is unique.
NIC information
View Network Card Information
Linux: ifconfig
windows: ipconfig
- ensxx: a network card used to communicate with the outside world;
- lo: Loop-back network card for local communication;
linux Close/Open Network Card: sudo ifconfig ensxx down/up
Classification of ip and ip addresses
ip is divided into ipv4 and ipv6
The ip address is divided into:
- Class A address
- Class B address
- Class C address
- Class D address -- for multicast
- Class E Address - Retained Address, Useless since ipv6 was born
- Private ip
Unicast - One-to-One
Multicast--One to Many
Broadcasting - many-to-many
port
ip: identification computer;
Port: Identify the process on the computer (running program);
ip and ports are used together to uniquely identify the host application and communicate with the unified software.
Port classification
Well known ports
Fixed the port number assigned to a particular process, which is generally not available to other processes.
Most of the ports less than 1024 are well-known ports.
The range ranges from 0 to 1023.
Dynamic port
Unfixed allocation, dynamic allocation, port number released after use;
Range 1024-65535;
socket
The concept of socket
Socket is a way of inter-process communication, which can realize inter-process communication between different hosts, that is, socket is a necessary thing for network communication.
Create socket
Create sockets:
import socket soc = socket.socket(AddressFamily, Type)
The function socket.socket creates a socket with two parameters:
Address Family: Optional AF_INET (for internet inter-process communication) and AF_UNIX (for inter-process communication on the same machine);
Type: Socket type, optional SOCK_STREAM (stream socket, mainly for TCP protocol)/SOCK_DGRAM (datagram socket, mainly for UDP socket);
Create tcp sockets
import socket soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ... soc.close()
Create udp sockets
import socket soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ... soc.close()
udp
udp uses socket to send data
Send messages in the same LAN;
If you use virtual machines and windows, you need to use bridge mode to ensure that in the same LAN;
import socket def main(): # Create a udp socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Using sockets to send and receive data udp_socket.sendto(b"hahaha", ("193.168.77.1", 8080)) # Close udp_socket.close() if __name__ == "__main__": main()
Several cases of udp sending data:
- Adding b before quotation marks of fixed data can not be used for user-defined data.
- User-defined data is sent and encoded using. encode("utf-8").
- User circularly sends data
- Users can send data circularly and exit
Only the last case, complete code, is posted.
import socket def main(): # Create a udp socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while 1: # Get the data to be sent from the keyboard send_data = input("Please enter the data you want to send:") if send_data == "exit": break # Using sockets to send and receive data udp_socket.sendto(send_data.encode("utf-8"), ("193.168.77.1", 8080)) # Close udp_socket.close() if __name__ == "__main__": main()
udp receives data
The received data is a tuple. The first part of the tuple is the content sent by the sender, and the second part is the ip address and port number of the sender.
import socket def main(): udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) localaddr = ('', 8080) udp_socket.bind(localaddr) # You must bind your computer's ip and port # receive data recv_data = udp_socket.recvfrom(1024) # The variable recv_data stores a tuple, such as (b'haha', ('192.168.77.1', 8888)). recv_msg = recv_data[0] send_addr = recv_data[1] # print("%s Sent:%s" % (str(send_addr), recv_msg.decode("utf-8"))) # Data sent by linux is decoded by utf8 print("%s Sent:%s" % (str(send_addr), recv_msg.decode("gbk"))) # Data sent by windows is decoded by gbk udp_socket.close() if __name__ == "__main__": main()
Summary of udp receiving and sending data
The process of sending data:
- Create sockets
- send data
- Close
The process of receiving data:
- Create sockets
- Binding local own information, ip and port
- receive data
- Close
Port binding issues
- If there is no binding port when you send data, the operating system will randomly allocate a port to you, and the same port is used for circular transmission.
- You can also bind ports before sending data.
Example of udp binding port itself when sending message
import socket def main(): # Create a udp socket udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Binding port udp_socket.bind(('192.168.13.1', 8080)) while 1: # Get the data to be sent from the keyboard send_data = input("Please enter the data you want to send:") if send_data == "exit": break # Using sockets to send and receive data udp_socket.sendto(send_data.encode("utf-8"), ("193.168.77.1", 8080)) # Close udp_socket.close() # Press ctrl+c to exit if __name__ == "__main__": main()
However, it should be noted that the same port can not be used by two different programs at the same time.
Single, half-duplex, full-duplex
Understanding of Single Work, Half Duplex and Full Duplex
Simplex:
Only one-way transmission of information, others receive, others can not reply to the message, such as broadcasting;
Half duplex:
Both can send messages, but only one person can send messages at the same time, such as a walkie-talkie.
Full duplex:
Both of them can send messages at the same time, such as telephone calls.
udp receives and sends data using the same socket
"""socket Sockets are full duplex""" import socket def main(): udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) udp_socket.bind(('192.168.13.1', 8080)) # Let the user enter the ip address and port to send dest_ip = input("Please enter the data you want to send. ip Address:") dest_port = int(input("Please enter the port number of the data you want to send:")) # Get the data to be sent from the keyboard send_data = input("Please enter the data you want to send:") # Using sockets to send and receive data udp_socket.sendto(send_data.encode("utf-8"), (dest_ip, dest_port)) # Sockets can send and receive data at the same time. recv_data = udp_socket.recvfrom(1024) print(recv_data) # Close udp_socket.close() # Press ctrl+c to exit if __name__ == "__main__": main()
The socket is full duplex, because now the interpreter can only follow the process, step by step, after learning the process thread co-operation can be done.
tcp
tcp-reliable transmission
Mechanism adopted by tcp
- Using Send Response Mechanism
- Timeout retransmission
- Error checking
- Flow control and congestion management
The difference between tcp and udp
- tcp is safer and more reliable than udp.
- Connection oriented
- Orderly data transmission
- Retransmit lost data
- Discard duplicate packets
- Error-free data transmission
- Blocking/Flow Control
tcp, udp application scenario
tcp application scenario: download, send messages
udp application scenarios: telephone, live video, etc.
tcp client
tcp client sends data
import socket def main(): # 1. Create sockets for tcp tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. Link Server tcp_socket.connect(('193.168.11.1', 8080)) # 3. Send/receive messages send_data = input("Please enter the message you want to send:") tcp_socket.send(send_data.encode("utf-8")) # 4. Close sockets tcp_socket.close() if __name__ == "__main__": main()
tcp Server
Monitor sockets, specifically for monitoring;
Acept corresponds to a newly created socket. When a request is received by the listener socket, the request is assigned to the new socket, so that the listener socket can continue to listen, and the new socket serves the hook segment.
import socket def main(): # Create tcp sockets tcp_service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_service_socket.bind(('', 8080)) # Change the default socket from active to passive tcp_service_socket.listen(128) # Waiting for Client Links new_client_socket, client_addr = tcp_service_socket.accept() print("The client address of the link is:", client_addr) # Receiving requests from clients recv_data = new_client_socket.recvfrom(1024) print(recv_data) # Send back messages to clients new_client_socket.send("hahahah".encode("utf-8")) new_client_socket.close() tcp_service_socket.close() if __name__ == '__main__': main()
The parameters in listen indicate that only 128 links are allowed at the same time.
Operating Principle of QQ Unbound Port-Extension
udp and tcp are used together.
Using QQ, login first, and then tell Tencent server the port that QQ is running, when sending a message, it forwards it to another QQ through Tencent server.
Unbound ports also have the advantage of allowing multiple QQ Qs to run on a single computer.
The difference between recv and recvfrom
recvfrom contains not only the data sent, but also the information of the people who sent the data.
There's only data in recv.
tcp client server process combing
tcp server process carding
- Create server sockets
- Binding local information
- Change the default socket from active to passive
- Waiting for client links, blocking
- After being linked by the client, a new customer service socket is created to serve the client.
- Receive messages sent by client, blocking
- After receiving the message sent by the client, return the message to the client
- Close the customer service socket and the server socket
tcp note
- tcp servers usually need to be bound, otherwise the client can not find the server.
- tcp client is not bound generally, because it is an active link server, so as long as the server's ip, port and other information is determined, the local client can be random.
- tcp server can change the active socket created by socket into passive socket through listen, which is what tcp server must do.
When the client needs to link to the server, it needs to use connect to link. udp does not need to link, but sends directly. but tcp must link first, only if the link succeeds can it communicate.
When a tcp client connects to the server, there will be a new socket on the server side. This socket is used to mark the client and serve the client alone.
The socket after liston is a passive socket that receives a link request from a new client, and the new socket returned by accept marks the new client.
Closing the isten socket means that the passive socket is closed, which will cause the new client to be unable to link to the server, but the client that has successfully linked before to communicate normally.
Closing the socket returned by accept means that the client has finished serving.
9. When the client's socket calls close, the server will recv to unblock, and the length of the return is 0, so the server can distinguish whether the client has been offline by the length of the return data.
tcp application case
Example 1 - Handling a business for a user:
"""It can be understood that a customer service in a bank handles business for people in line.""" import socket def main(): # 1. Create tcp sockets tcp_service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. Binding local information tcp_service_socket.bind(('', 8080)) # 3. Change the default socket from active to passive tcp_service_socket.listen(128) while 1: # 4. Waiting for Client Links new_client_socket, client_addr = tcp_service_socket.accept() print("The client address of the link is:", client_addr) # Receiving requests from clients recv_data = new_client_socket.recvfrom(1024) print(recv_data) # Send back messages to clients new_client_socket.send("hahahah".encode("utf-8")) # Close new_client_socket.close() tcp_service_socket.close() if __name__ == '__main__': main()
Example 2 - Serve the same user multiple times and determine whether a user has completed the service:
"""It can be understood that a customer service in a bank handles business for people in line.""" import socket def main(): # 1. Create tcp sockets tcp_service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. Binding local information tcp_service_socket.bind(('', 8080)) # 3. Change the default socket from active to passive tcp_service_socket.listen(128) while 1: # 4. Waiting for Client Links new_client_socket, client_addr = tcp_service_socket.accept() print("The client address of the link is:", client_addr) # Cyclic Purpose: Serve the same customer multiple times while 1: # Receiving requests from clients recv_data = new_client_socket.recvfrom(1024) print(recv_data) # If recv unblock, there are two ways # 1. Client sends data. # 2. The client calls close if recv_data: # Send back messages to clients new_client_socket.send("hahahah".encode("utf-8")) else: break # Close new_client_socket.close() tcp_service_socket.close() if __name__ == '__main__': main()
Example 3-tcp file download client and server:
File Download Client
import socket def main(): # 1. Create sockets tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. Get the ip, port of the server dest_ip = input("Please enter the server you want to link to ip: ") dest_port = input("Please enter the port you want to link to:") # 3. Link Server tcp_socket.connect((dest_ip, dest_port)) # 4. Get the name of the downloaded file want_file = input("Please enter the file you want to download:") # 5. Send the file name to the server tcp_socket.send(want_file.encode("utf-8")) # 6. Receive files to download file_data = tcp_socket.recv(1024) # 7. Write the data of the received file into a file if file_data: with open("[Duplicate]" + want_file, "wb") as f: f.write(file_data) # 8. Close sockets tcp_socket.close() pass if __name__ == '__main__': main()
File Download Server
import socket def send_file2client(new_socket, client_addr): # 1. Accept the file name sent by the client to download want_file = new_socket.recv(1024).decode("utf-8") print("Client %s The files to be received are:%s" % (str(client_addr), want_file)) # 2. Read file data file_data = None try: f = open(want_file, "rb") file_data = f.read() f.close() except Exception as e: print("The files you want to download %s Non-existent" % want_file) # 3. Send file data to client if file_data: new_socket.send(file_data) def main(): # 1. Create sockets tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. Binding local information tcp_socket.bind(('', 8080)) # 3. Sockets passively accept listen tcp_socket.listen(128) while 1: # 4. Waiting for the client's link accept new_socket, client_addr = tcp_socket.accept() # 5. Call function to send file to client send_file2client(new_socket, client_addr) # 7. Close sockets new_socket.close() tcp_socket.close() if __name__ == '__main__': main()