socket通信
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket client = socket.socket() # 拿电话 client.connect(('127.0.0.1',8080)) # 拨号 写的是对方的 IP和端口 port client.send(b"hello world") # 对别人说话 data = client.recv(1024) # 听别人说话 print(data) client.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket server = socket.socket() # 买手机 不传参数用的 TCP协议 server.bind(('127.0.0.1',8080)) # bind((host,port)) 插电话卡 server.listen(5) # 开机 半连接池 conn,addr = server.accept() # 接听电话 等着别人给你打电话 阻塞 data = conn.recv(1024) # 听别人说话 # 接收1024 个字节数据 阻塞 print(data) conn.send(b'hello baby~') # 给别人回话 conn.close() # 挂电话 server.close() # 关机
TCP粘包问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket # 买手机 client = socket.socket() # 拨号 client.connect(("127.0.0.1",8081)) # 说话 # client.send(b"hello sever") client.send(b'hello') client.send(b'world') client.send(b'baby') # 听话 data = client.recv(1024) print(data) # 挂电话 # client.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket # 买手机 server = socket.socket() # 拨号 server.bind(("127.0.0.1",8081)) # IP 与 port # 开机 server.listen(5) # 半连接池 # 接通 conn,addr = server.accept() # 听电话 # data = server.recv(1024) # print(data) data = conn.recv(5) # 听别人说话 接收1024个字节数据 阻塞 print(data) data = conn.recv(5) # 听别人说话 接收1024个字节数据 阻塞 print(data) data = conn.recv(4) # 听别人说话 接收1024个字节数据 阻塞 print(data) # 回话 conn.send(b"hello boy") # 挂电话 # conn.close() # 关电话 # server.close()
解决粘包问题
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket import struct import json # 买手机 client = socket.socket() # 拨号 client.connect(("127.0.0.1",8081)) # 说话 while True: msg = input("cmd:>>>").encode("utf-8") if len(msg) == 0:continue client.send(msg) # 1.先接收字典的报头 header_dict = client.recv(4) # 2.解析报头,获取字典的长度 dict_size = struct.unpack('i',header_dict)[0] # 解包的时候一定要加上索引 0 # 3.接收字典数据 dict_bytes = client.recv(dict_size) dict_json = json.loads(dict_bytes.decode("utf-8")) # 4.从字典中获取信息 print(dict_json) recv_size = 0 real_data = b'' while recv_size < dict_json.get('file_size'): # real_size = 102400 data = client.recv(1024) real_data += data recv_size += len(data) print(real_data.decode('gbk')) """ 1.如何将对方发送的数据收干净 """
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket import subprocess import json import struct # 买手机 server = socket.socket() # 拨号 server.bind(("127.0.0.1",8081)) # IP 与 port # 开机 server.listen(5) # 半连接池 # 接通 while True: conn,addr = server.accept() while True: try: cmd = conn.recv(1024) if len(cmd) == 0:break cmd = cmd.decode('utf-8') obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) res = obj.stdout.read() + obj.stderr.read() d = { "name":"jason", "file_size":len(res), "info":"hello boy good morning !" } # 1.先制作一个字典的报头 json_d = json.dumps(d) header = struct.pack('i',len(json_d)) # 2.发送字典报头 conn.send(header) # 3.发送字典 conn.send(json_d.encode('utf-8')) # 4.再发真实数据 conn.send(res) # conn.send(obj.stdout.read()) # conn.send(obj.stderr.read()) except ConnectionResetError: break conn.close()
连接循环+通信循环
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket # 买手机 client = socket.socket() # 拨号 client.connect(("127.0.0.1",8081)) while True: msg = input("cmd:>>>").encode("utf-8") if len(msg) == 0:continue client.send(msg) data = client.recv(1024) print(data)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import socket """ 服务端 固定的ip和port 24小时不间断提供服务 """ # 买手机 server = socket.socket() # # 生成一个对象 # 拨号 server.bind(("127.0.0.1",8081)) # IP 与 port # # 绑定ip和port # 开机 server.listen(5) # 半连接池 # 接通 while True: conn,addr = server.accept() # 等到别人来 conn就类似于是双向通 print(addr) # ('127.0.0.1', 51323) 客户端的地址 while True: try: data = conn.recv(1024) print(data) # b'' 针对mac与linux 客户端异常退出之后 服务端不会报错 只会一直收b'' if len(data) == 0:break conn.send(data.upper()) except ConnectionResetError as e: print(e) break conn.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import struct res = "sdhsfjdshjflkjdsafhjdsajflkhdlkjafhkjsadhfkjjsadkfhkjlsadhkfhksadfjjhsadfsdkaf" print("最原始的",len(res))# 最原始的 78 # 当原始数据特别大的时候, i 模式打包不了,需要更换模式 # 如果遇到数据量特别大的情况 该如何解决? d = { 'name':"jason", "file_size":34355555555555555, "info":"为大家的骄傲" } import json json_d = json.dumps(d) print(len(json_d))# 97 resl = struct.pack('i',len(json_d)) print(len(resl))# 4 res2 = struct.unpack('i',resl)[0] print("解包之后",res2) # 解包之后 97
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import subprocess cmd = input("cmd:>>>").strip() obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) print(obj.stdout.read().decode('gbk')) # 正确命令返回的结果 print(obj.stderr.read().decode('gbk')) # 错误的命令返回的结果 # subprocess获取到的数据 拿完就没有了 不能重复的拿 print(obj.stdout.read().decode('gbk')) # 正确命令返回的结果 print(obj.stderr.read().decode('gbk')) # 错误的命令返回的结果
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Socket(套接字) 127.0.0.1本机回还地址 只能自己识别自己 其他人无法访问 send与recv对应 不要出现两边都是相同的情况 recv是跟内存要数据 至于数据的来源 你无需考虑 TCP特点 会将数据量比较小的并且时间间隔比较短的数据 一次性打包发送给对方 socket最简单版本 解决粘包问题的最复杂版本 from socket import SOL_SOCKET,SO_REUSEADDR sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) # 就是他,在 bind前面加 解决粘包问题 服务端 1.先制作一个发送给客户端的字典 2.制作字典的报头 3.发送字典的报头 4.发送字典 5.再发真实数据 客户端 1.先接受字典的报头 2.解析拿到字典的数据长度 3.接受字典 4.从字典中获取真实数据的长度 5.接受真实数据 写一个上传电影的功能 1.循环打印某一个文件夹下面的所有的文件 2.用户选取想要上传的文件 3.将用户选择的文件上传到服务端 4.服务端保存该文件 1.直接获取数据1024 2.制作一个数据的报头 3.先发个字典 然后再发真实数据