💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] ## 1. socket简介 ### 1. 本地进程间通信有很多种方式 * 队列 * 同步 ### 2. 网络之间的通信 ![](https://box.kancloud.cn/d6f4d6d73bec418eae01bed4d6d7a7ab_795x607.png) 1. 在本地可以通过PID表示一个进程,但是网络中这样是行不通的。 2. tcp/ip帮我们解决了这个问题,网络层(IP地址)可以唯一标识网络中的主机,而传输层(协议+端口)可以标识主机中的应用程序(进程) 3. 这样利于IP地址,协议,端口就可以标识网络中的进程了。 ## 2. 创建socket `socket.socket(AddressFamily, Type)` 函数 socket.socket 创建⼀个 socket, 返回该 socket 的描述符, 该函数带有 > * 两个参数: > 1. Address Family: > 可以选择 AF_INET(⽤于 Internet 进程间通信) 或者AF_UNIX(⽤于同⼀台机器进程间通信) ,实际⼯作中常⽤AF_INET > 2. Type: > 套接字类型, 可以是 SOCK_STREAM(流式套接字, 主要⽤于TCP 协议) 或者 SOCK_DGRAM(数据报套接字, 主要⽤UDP协议) 1. 创建⼀个tcp socket(tcp套接字) ~~~ import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print 'Socket Created' ~~~ 2. 创建⼀个udp socket(udp套接字) ~~~ import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) print 'Socket Created ~~~ ### 2.1 UDP ⽤户数据报协议, 是⼀个⽆连接的简单的⾯向数据报的`传输层`协议。 #### UDP特点: > UDP是⾯向⽆连接的通讯协议, UDP数据包括⽬的端⼝号和源端⼝号信息,由于通讯不需要连接, 所以可以实现⼴播发送。 UDP传输数据时有⼤⼩限制, 每个被传输的数据报必须限定在64KB之内。 UDP是⼀个不可靠的协议, 发送⽅所发送的数据报并不⼀定以相同的次序到达接收⽅。 #### 适⽤情况 > UDP是⾯向消息的协议, 通信时不需要建⽴连接, 数据的传输⾃然是不可靠 > 的, UDP⼀般⽤于多点通信和实时的数据业务, ⽐如 > 语⾳⼴播 > 视频 > QQ > TFTP(简单⽂件传送) > SNMP(简单⽹络管理协议) > RIP(路由信息协议, 如报告股票市场, 航空信息) > DNS(域名解释) > #### client端 ~~~ from socket import * #1. 创建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) #2. 准备接收⽅的地址 sendAddr = ('192.168.1.103', 8080) #3. 从键盘获取数据 sendData = raw_input("请输⼊要发送的数据:") #4. 发送数据到指定的电脑上 udpSocket.sendto(sendData, sendAddr) #5. 关闭套接字 udpSocket.close() ~~~ server端 ~~~ #coding=utf-8 from socket import * #1. 创建套接字 udpSocket = socket(AF_INET, SOCK_DGRAM) # udp绑定信息 绑定本地的相关信息, 如果⼀个⽹络程序不绑定, 则系统会随机分配 bindAddr = ('', 7788) # ip地址和端⼝号, ip⼀般不⽤写, 表示本机的任何⼀个ip udpSocket.bind(bindAddr) #3. 等待接收对⽅发送的数据 recvData = udpSocket.recvfrom(1024) # 1024表示本次接收的最⼤字节数 #4. 显示接收到的数据 print recvData #5. 关闭套接字 udpSocket.close() ~~~ #### 通信过程 ![](https://box.kancloud.cn/2a55f8c912feeb4f40e0b30ded3cf5bc_735x543.png) #### 广播 > 单播 点对点 > 多播 一对多 > 广播 一对所有 > * 广播udp可以使用,tcp没有 1. 服务端 ~~~ import socket s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) PORT = 7788 # '<broadcast>'会根据实际情况判断广播地址,写真实广播地址也可以就是不通用 network = '<broadcast>' s.sendto('hello everybody'.encode('utf-8'), (network, PORT)) while True: (content,address) = s.recvfrom(1024) print("receive from %s: %s"%(address,content.decode('utf-8'))) ~~~ 2. 客户端 ~~~ from socket import * udp = socket(AF_INET,SOCK_DGRAM) udp.bind(('',7788)) data = udp.recvfrom(1024) content,source = data # 和Scala类似 print(content.decode("utf-8")) # 解码 udp.sendto('hello'.encode('utf-8'),source) ~~~