1、套接字介绍
socket起源于Unix,遵循“一切皆文件”出发点,都可以用“打开open –> 读写write/read –> 关闭close”模式来操作。
在设计模式中,Socket把复杂的TCP/IP协议族隐藏在Socket接口后面,Socket去组织数据,以符合指定的协议。Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。
2、套接字服务过程(TCP协议)

3、一个简单服务器示例
       s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)        
 · 协议族,通常为AF_INET,表示互联网协议族(TCP/IP协议族)。
 · socket类型:SOCK_STREAM,流式套接字提供可靠的、面向连接的通信流:它使用TCP协议,从而保证了数据传输的正确性和顺序性(TCP:可靠的、重传、有连接的,一般用于控制命令)。
3.1 server
        s.listen()    0成功,-1失败
 · 服务器端套接字一直处于监听状态,不受客户端连接的影响。
 · 接收到客户端套接字的连接请求,就会响应客户端套接字的请求,建立一个新的线程,并把服务器端套接字的描述发送给客户端。
        s.accept()  
 · 返回新的socket,用于完成和本次接受的客户端通信。从已完成连接的列表,返回连接;没有连接,线程则进入阻塞睡眠状态。
import socket
import struct
import json
from tqdm import tqdmserver=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serversocketaddr=('127.0.0.1',12345)
server.bind(serversocketaddr)
server.listen(1024)clientsocket,addr=server.accept()
print("Connection from %s has been established!" % clientsocket)# recv多条数据出现粘包现象,可通过增加header解决,规定内容长度,获取指定内容
print("--------------BEGIN-----------------")
header_len_bytes=clientsocket.recv(4)   # 接收报头长度,固定4字节
header_len=struct.unpack("i",header_len_bytes)[0]
header=clientsocket.recv(header_len).decode()
header=json.loads(header)
file_size=header["file_size"]
file_data=clientsocket.recv(file_size)print("[{}]{}".format(type(file_data),file_data))
print("--------------END-----------------","\n")
server.close()3.2 client
import socket
import os.path
import json
import structclient=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
serversocketaddr=('127.0.0.1',12345)
client.connect(serversocketaddr)file_name="/Users/test/client.png"
file_size=os.path.getsize(file_name)
with open(file_name,'rb') as file:file_data=file.read()header = {"file_size": file_size,"file_name": file_name}header_bytes = json.dumps(header).encode()header_length = struct.pack("i", len(header_bytes))client.send(header_length)client.send(header_bytes)# client.sendall(file_data)client.send(b"<END>")client.close()3.3 data exchange
· 内容以字节码传输(bytes)
 · s.send()  发送内容,只支持字节类型.多个数据包存在粘包情况,需要处理。
 ·  s.sendall()  发送数据,直到所有的数据都发送完成或报错
3.4 RUN(控制台)
· 开始进程
     /usr/local/bin/python3.7 server_file_name    #python运行目录 +运行文件
     /usr/local/bin/python3.7 client_file_name
· 结束进程
     sudo lsof -i :port   # 终端查询当前端口的详情,获取到PID
     kill -9 PID