foreword
"I'm on a business trip" today, and I'm full of trivial matters at night. I really can't concentrate on learning what content, but I still don't want the flag of one article a day to fall down. I can only refer to other people's blogs to learn more about python sockets. For application, I will do experiments in the follow-up class. After learning more in-depth knowledge, I will make up my own understanding.
(11.4) Updated
Socket
Any application, such as browsing the web, browsing Douyin, chatting on WeChat, etc., communicates through TCP/IP.
Socket is a set of encapsulations of the TCP/IP protocol, which can be understood as an interface for communication between the two parties .
Socket is also known as "socket". Application programs usually send requests to the network or respond to network requests through "sockets", so that hosts or processes on a computer can communicate.
Just like sending and receiving express delivery, the recipient and sender do not need to know how the intermediate express delivery is transmitted, they only need to care whether the express delivery has been sent or received. The specific express transportation process in the middle is managed by the express company.
Corresponding to information transmission, Socket is equivalent to a courier company, playing an intermediate role.
The current socket programming is mostly used for network communication through the tcp protocol.
Common Socket Object Methods and Properties
name | describe |
---|---|
Server | server socket method |
s.bind(ADDR) | Bind an address (hostname, port number pair) to a socket |
s.listen([backlog]) | Set and start the TCP listener, must be at least 0 if backlog is specified (set to 0 if lower than 0); |
s.accept() | Passively accept TCP client connections, waiting until a connection arrives (blocking) |
client | Client Socket Methods |
s.connect() | Actively initiate a TCP server connection |
s.connect_ex() | An extended version of connect() that returns the problem as an error code instead of throwing an exception |
common | Ordinary socket methods |
s.recv() | Receive TCP messages |
s.recv_into() | Receive TCP message to specified buffer |
s.send() | Send TCP messages |
s.sendall() | Send a TCP message in its entirety |
s.recvfrom() | Receive UDP messages |
s.recvfrom_into() | Receive UDP message to specified buffer |
s.sendto() | Send UDP messages |
s.getpeername() | Remote address to connect to socket (TCP) |
s.getsockname() | the address of the current socket |
s.getsockopt() | Returns the value of the given socket option |
s.setsockopt() | Sets the value of the given socket option |
s.shutdown() | close connection |
s.close() | close socket |
s.detach() | Close the socket without closing the file descriptor, return the file descriptor |
s.ioctl() | Control socket mode (Windows only) |
block | Blocking-oriented socket methods |
s.setblocking() | Set the blocking or non-blocking mode of the socket |
s.settimeout() | Set the timeout for blocking socket operations |
s.gettimeout() | Get the timeout for blocking socket operations |
file method | File Oriented Sockets Methods |
s.fileno() | the socket's file descriptor |
s.makefile() | Create a file object associated with the socket |
Attributes | data attribute |
s.family | socket family |
s.type | socket type |
s.proto | socket protocol |
C/S communication process
The basic process on the server side:
1. Initialize socket()
2. Use bind() to bind ip and port number
3 Use listen() to listen to messages
4. Obtain the client's socket address accept()
5. Use recv() to receive data, and send() to send data to interact with the client
The basic flow of the client:
1. Initialize socket()
2. Use ip and port number connect() to connect to the server
3. Use recv() to receive data, send() to send data to interact with the server
Take tcp three-way handshake as an example:
When the server S performs socket.listen(), it initiates a connection request to the server, and the first handshake
When client C performs socket.connect(), when the client sends the first message to the server, the second handshake
The server S responds to the socket.accpet() server, and the third handshake
connection succeeded
code demo
ps: It seems that the UDP port can only be used once
server.py
import socket #导入socket库
from time import ctime
import json
import time
HOST = ''
PORT = 9001
ADDR = (HOST, PORT)
BUFFSIZE = 1024 #定义一次从socket缓冲区最多读入1024个字节
MAX_LISTEN = 5 #表示最多能接受的等待连接的客户端的个数
def tcpServer():# TCP服务
# with socket.socket() as s:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:#AF_INET表示socket网络层使用IP协议,SOCK_STREAM表示socket传输层使用tcp协议
# 绑定服务器地址和端口
s.bind(ADDR)
# 启动服务监听
s.listen(MAX_LISTEN)
print('等待用户接入……')
while True:
# 等待客户端连接请求,获取connSock
conn, addr = s.accept()
print('警告,远端客户:{} 接入系统!!!'.format(addr))
# with conn:
while True:
print('接收请求信息……')
# 接收请求信息
data = conn.recv(BUFFSIZE) #读取的数据一定是bytes类型,需要解码成字符串类型
if not data:
break
info = data.decode()
# print('data=%s' % data)
print(f'接收数据:{info}')
# 发送请求数据
conn.send(f'服务端接收到信息{info}'.encode())
print('发送返回完毕!!!')
conn.close()
s.close()
# 创建UDP服务
def udpServer():
# 创建UPD服务端套接字
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
# 绑定地址和端口
s.bind(ADDR)
# 等待接收信息
while True:
print('UDP服务启动,准备接收数据……')
# 接收数据和客户端请求地址
data, address = s.recvfrom(BUFFSIZE)
if not data:
break
info = data.decode()
print(f'接收请求信息:{info}')
s.sendto(b'i am udp,i got it', address)
s.close()
if __name__ == '__main__':
while True:
choice = input('input choice t-tcp or u-udp:')
if choice != 't' and choice != 'u':
print('please input t or u,ok?')
continue
if choice == 't':
print('execute tcpsever')
tcpServer()
else:
print('execute udpsever')
udpServer()
client.py
import socket
from time import ctime
HOST = 'localhost'
PORT = 9001
ADDR = (HOST, PORT)
BUFFSIZE = 1024
def tcpClient():
# 创建客户套接字
with socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) as s:
# 尝试连接服务器
s.connect(ADDR)
print('连接服务成功!!')
# 通信循环
while True:
inData = input('pleace input something:')
if inData == 'q':
break
# 发送数据到服务器
# inData = '[{}]:{}'.format(ctime(), inData)
s.send(inData.encode())
print('发送成功!')
# 接收返回数据
outData = s.recv(BUFFSIZE)
print(f'返回数据信息:{outData}')
# 关闭客户端套接字
s.close()
def udpClient():
# 创建客户端套接字
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
while True:
# 发送信息到服务器
data = input('please input message to server or input \'quit\':')
if data == 'quit':
break
data = '[{}]:{}'.format(ctime(), data)
s.sendto(data.encode('utf-8'), ADDR)
print('send success')
# 接收服务端返回信息
recvData, addrs = s.recvfrom(BUFFSIZE)
info = recvData.decode()
print(f'recv message : {info}')
# 关闭套接字
s.close()
if __name__ == '__main__':
while True:
choice = input('input choice t-tcp or u-udp or q-quit:')
if choice == 'q':
break
if choice != 't' and choice != 'u':
print('please input t or u,ok?')
continue
if choice == 't':
print('execute tcpsever')
tcpClient()
else:
print('execute udpsever')
udpClient()
You can enter the command on the windows command line interface to check whether the port is occupied: netstat -an|find /i "port number"
It can be seen that 9001 is not occupied
After running server.py
reference: