socket模块(套接字模块)
socket模块(套接字模块)
一、最简单版本(互传一次就结束)
# 客户端
import socket
client = socket.socket()
client.connect(('127.0.0.1', 8080)) # 8080是端口号
'''
来源百度百科
'127.0.0.1'是本机回还地址,不属于任何一个有类别地址类。它代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。在Windows操作系统中也有相似的定义,所以通常在安装网卡前就可以ping通这个本地回环地址。一般都会用来检查本地网络协议、基本数据接口等是否正常的。
'''
client.send(b'hello, baby! I love you!')
msg = client.recv(1024)
print(msg.decode('utf-8'))
# 服务端
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080)) # 服务端绑定ip和端口号
server.listen(5) # 半连接池,待连接(处于一个队列中)该服务端的客户端数不能超过5个
# 有一个房间,房间内是客户端和服务端,房间外有五张凳子,最多支持5个待连接客户端,再多就会报错
conn,addr = server.accept()
msg = conn.recv(1024)
print(msg.decode('utf-8'))
conn.send(b'I love you too!')
conn.close() # 关闭连接
server.close() # 关闭服务器
二、升级版(服务端不间断服务,客户端可以重复发送命令)
# 客户端
import json
import socket
import struct
client = socket.socket()
client.connect(('127.0.0.1', 8080))
while True:
cmd = input('>>>:').encode('utf-8')
print(type(cmd)) # <class 'bytes'>
if len(cmd) == 0:
continue
client.send(cmd)
# 1.接收报头
header_length = client.recv(4)
print(type(header_length)) # <class 'bytes'>
# 2.解包得到字典的长度
d_length = struct.unpack('i', header_length)[0]
print(type(d_length)) # <class 'int'>
# 3.接收字典
d = client.recv(d_length)
print(type(d)) # <class 'bytes'>
# 4.由字典拿到数据的长度
real_d = json.loads(d)
print(type(real_d)) # <class 'dict'>
data_length = real_d['info_length']
print(data_length)
print(type(data_length)) # <class 'int'>
# 5.接收真实数据
with open('file', 'a', encoding='utf-8') as f:
real_length = 0
while real_length < data_length:
data = client.recv(1024)
real_length += len(data)
f.write(data.decode('gbk'))
# 服务端
import json
import socket
import subprocess
import struct
from socket import SOL_SOCKET, SO_REUSEADDR
server = socket.socket()
# 避免因操作系统未及时回收端口造成的端口已被占用的问题
server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
conn, addr = server.accept()
while True:
try:
cmd = conn.recv(1024).decode('utf-8')
if len(cmd) == 0:
break
obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(type(obj))
msg = obj.stdout.read() + obj.stderr.read()
print(type(msg)) # <class 'bytes'>
# 1.将数据长度放到字典中,将字典长度打包-报头
d = {'info_length': len(msg)}
json_d = json.dumps(d)
print(type(json_d)) # <class 'str'>
header = struct.pack('i', len(json_d))
print(header) # b'\x15\x00\x00\x00'
# 2.发送报头
conn.send(header)
# 3.发送字典
conn.send(json_d.encode('utf-8'))
# 4.发送真实数据
conn.send(msg)
except ConnectionResetError: #
break
conn.close()
三、TCP传输的特点
应用程序所需要的数据,都是跟所在的那台计算机内存去要(所有数据传输都遵循这个规则)
会将数据量较小的并且时间间隔比较短的数据一次性打包发送给对方
# 客户端
import socket
client = socket.socket() # 拿电话
client.connect(('127.0.0.1', 8080)) # 拨号 写的是对方的ip和port
client.send(b'hello')
client.send(b'world')
client.send(b'baby')
client.send(b'baby')
# 服务端
import socket
server = socket.socket() # 买手机 不传参数默认用的就是TCP协议
server.bind(('127.0.0.1', 8080)) # bind((host,port)) 插电话卡 绑定ip和端口
server.listen(5) # 开机 半连接池
conn, addr = server.accept() # 接听电话 等着别人给你打电话 阻塞
data = conn.recv(1024) # 听别人说话 接收1024个字节数据 阻塞
print(data)
data = conn.recv(1024) # 听别人说话 接收1024个字节数据 阻塞
print(data)
data = conn.recv(1024) # 听别人说话 接收1024个字节数据 阻塞
print(data)
# 输出内容 理论上应该是在一行显示...
b'hello'
b'worldbabybaby'
b''
四、arp协议
- 先由IP地址找到对方,然后对方将自己的mac地址发回来
五、粘包问题
假设一种情况
小明的妈妈给小明零花钱,给了他50块钱,放在了零钱罐中,但都是硬币,小明还小,两只手一次最多只能拿十个硬币,而且规定,小明只有在妈妈给他零花钱的时候才能从零钱罐中拿钱,所以,虽然妈妈每次都给小明50块的零花钱,但是小明实际上每次只能拿到10块钱。
假设另一种情况
小明和小红在玩一个游戏,游戏规则如下:小红和小明面对面坐在桌子两侧,桌子上有三个罐子,小红小明各有一个,小红手上的罐子里有三个玻璃球,规定小红将自己罐子里的球倒入桌上的空罐子,倒三次;小明在小红将球放入罐子后,拿起罐子,将里面的球倒入自己的罐子中,也倒三次。游戏开始,小红往罐子里倒了球,小明拿起罐子,将球倒入自己的罐子中,发现一次性倒出三个球。他问小红,小红说她一次性讲球全部倒进去了
这两种情况分别是,一次拿少了,一次拿多了
六、解决粘包问题
- 解决粘包问题的关键在于,每一次拿的量是未知的
- 那么我们就要设法让服务端知道我们每一次传过去的数据的长度是多少
服务端
1.先制作一个发送给客户端的字典
2.制作字典的报头
3.发送字典的报头
4.发送字典
5.再发真实数据
客户端
1.先接受字典的报头
2.解析拿到字典的数据长度
3.接收字典
4.从字典中获取真实数据的长度
5.接收真实数据
socket模块(套接字模块)的更多相关文章
- socket套接字模块及黏包现象
一.socket套接字模块 socket概念 socket层 理解socket Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socket其实就是一个门面模 ...
- python 全栈开发,Day33(tcp协议和udp协议,互联网协议与osi模型,socket概念,套接字(socket)初使用)
先来回顾一下昨天的内容 网络编程开发架构 B/S C/S架构网卡 mac地址网段 ip地址 : 表示了一台电脑在网络中的位置 子网掩码 : ip和子网掩码按位与得到网段 网关ip : 内置在路由器中的 ...
- socket概念 套接字
理解socket soxket因为TCP是面向流的,你发的信息如果很多很快,TCP这样就会形成黏包 Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口.在设计模式中,Socke ...
- sanic官方文档解析之Custom Protocols(自定义协议)和Socket(网络套接字)
1,Custom Protocol:自定义协议 温馨提示:自定义协议是一个高级用法,大多数的读者不需要用到此功能 通过特殊的自定义协议,你可以改变sanic的协议,自定义协议需要继承子类asyncio ...
- iOS - Socket 网络套接字
1.Socket 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个 Socket.Socket 又称 "套接字",应用程序通常通过 "套接字& ...
- Socket称"套接字"
Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 二.利用Socket建立网络连接的步骤 建立Socket连接至少需要一对 ...
- Win2 Socket(套接字)相关 API
Socket(套接字) 作者信息 肖进 单位:南京中萃食品有限公司 资讯部 邮箱:xiaoj@njb.swirebev.com 电话:025-58642091 与socket有关的一些函数介绍 1.读 ...
- Python之socket(套接字)
Socket 一.概述 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. ...
- 网络编程(socket,套接字)
服务端地址不变 ip + mac 标识唯一一台机器 ip +端口 标识唯一客户端应用程序 套接字: 网络编程 网络编程 一.python提供了两个级别访问的网络服务 低级别的网络服务支持基本的 S ...
随机推荐
- WebViewJavascriptBridge(H5与原生交互)
https://github.com/wangjiaojiao77/WebViewJavascriptBridge(IOS)和 https://github.com/wangjiaojiao77/Js ...
- 【填坑】python3 manage.py migrate:?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default'
问题: WARNINGS:?: (mysql.W002) MySQL Strict Mode is not set for database connection 'default' H ...
- C++-有感
今日在图书馆待了差不多一天,我都忘了我吃饭了没,拿着看视频学习,没啦,主要还是看书,突然感觉有点写不动了. 明天开始不带电脑了,准备把数据结构书重新过一遍,算了,还是不用C++写了,感觉C++居然做题 ...
- 0121 spring-boot-redis的使用
redis是什么呢?redis,属于NoSQL的一种,在互联网时代,起到加速系统的作用. redis是一种内存数据库,支持7种数据类型的存储,性能1S 10w次读写: redis提供的简单的事务保证了 ...
- Web API幂等、超时优化
幂等 当涉及业务数据的变更,不是简单的数据查询时, 在调用方相同条件有效重复请求时,就需要保持业务系统数据之间的一致性,不管请求多少次都会返回相同的结果. 比如一个订单支付接口,第一次请求返回支付成功 ...
- php 法大大对接
通过编写扩展实现, 实现两种方式签署 1, 存证签署 存证签署流程 /** *个人 *客户在平台注册(姓名,身份证,手机号)---->三要素验证----->获取客户编号-------> ...
- Android 的UI基础布局的学习
一. 今天学习了Android 的UI基础布局的部分,绝大多数的布局都在Androidstudio的这个界面里,如下: 在左边的框里的palette的内部,包含了的大多数的布局所要用的button按钮 ...
- 状态压缩DP入门题
. /*本题为状态压缩题 题目大意 : 一个矩阵里有很多格子,每个格子有两种状态,可以放牧和不可以放牧, 可以放牧用1表示,否则用0表示,在这块牧场放牛,要求两个相邻的方 格不能同时放牛(不包括斜着的 ...
- 【正确使用vim编辑器的姿势】
"vi:可视化接口(Visual Interface) vim:是vi的增强版(vi iMprove) vi编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中 ...
- 查看Oracle的SID的方式
1 使用组合键“Win + R”打开运行对话框,在输入框中输入 regedit 并回车打开“注册表编辑器”. 2 在“注册表编辑器”对话框,依次展开 HKEY_LOCAL_MACHINE\SOF ...