Socket简单实现ssh笔记
Scoket概念:
socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 我们知道网络 通信 都 是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务,如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。 建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。(利用IP和端口实现两个设备的通信)。
Socket核心方法:
接收端:
import socket
socket.TCP/IP
listen(ip,port)
waiting()#等待数据
recv()#接收数据
send()#再发送数据发送端:
import socket
socket.TCP/IP
connect(a.ip,a.port)#接受端主机的IP,端口(port:端口号)
socket.send(hello)#发送的数据sendall()名义上是一次性发送所有的数据,但是由于系统原因还是有限制的
socket.recv()#接收数据
socket.close()#关闭实例列举:
服务器端:
import socket
server=socket.socket()#设置连接
server.bind((“localhost”,8888))#绑定连接(参数是一个元组)
server.listen(5)#监听
conn,addr=server.accept()#等待
data=conn.recv(1024)#接收(是byte类型的,需要转换(一般编为utf-8))
conn.sendall(data)#一次性发送所有数据(由于系统原因,是发送不了所有的数据的)
server.close()客户端:
import socket
client=socket.socket()
client=connect((“localhost”,8888))#建立连接,参数是一个元组
data=input().strip()#手工输入的是unicode类型,但是再传输的时候是要编码的
client.send(data.encode(“utf-8”))#发送数据
data=client.recv(1024)#收到的数据是utf-8编码的,所以直接输出是乱码
client.close()粘包:
当你连续的调用send()时,由于接收时recv()有大小限制,会发生发送的数据量大于接收的数据量,导致接收的数据不是你期待的数据,这个时候就发生了粘包(两次发送的数据被同一次接收) 为了避免这种错误,我们通常会设计反馈,即你发送一次数据,我们会吧发送的数据反馈给发送给你。这样两次发送中间夹杂着一次接收,避免了数据在缓冲中导致粘包。
一些注意的地方:
- 发送与接收的类型:
我们在Python3中,默认是Unicode,而在发送数据(send)时,函数send()的参数类型是:Byte,所以我们要进行数据的转换:
str==>bytes | bytes==>str |
a=”qweqwe” =>a的类型为str str==>bytes b=a.encode(“utf-8”) |
b=b”hello word” =>b为bytes类型 bytes==>str s=b.decode(“utf-8”) |
- 数据的校验:
字符串类型的,我们可以利用hashlib包中的md5算法来检验
文件类型的,我们可以对比两个文件的区别:
diff file1 file2 |
观察两个文件是否一致(文件检测) |
SocketServer:
这个比较方便,它集成了一些东西,很方便的,只是server端改变了一下书写方式,客户端不用改变
代码如下:
#this is server
import socketserver
class MyTCPHandler(socketserver.BaseRequestHandler):#类名随意,但是继承的不能改变
def handle(self):#系统会自动调用这个函数,我们只需要在这个函数中写我们要实现的方法就可以了
while True:
try:
self.data=self.request.recv(1024).strip()
print("{} wrote".format(self.client_address))
print(self.data)
self.request.send(self.data.upper())
except ConnectionResetError as e:
print("error: ",e)
break
if __name__ =="__main__":
HOST,PORT="localhost",9999#声明IP与端口
server=socketserver.ThreadingTCPServer((HOST,PORT),MyTCPHandler)#设置连接
server.serve_forever()#建立连接,然后系统在连接成功以后会自动调用函数handle()
#this is client
import socket
client=socket.socket()
client.connect(("localhost",9999))
while True:
cmd=input(">>").strip()
if cmd =="":
continue
client.send(cmd.encode())
data=client.recv(1024)
print(data)
附:
socket一个最简单的通信:
#服务器端:
import socket
server=socket.socket()
server.bind(("localhost",8888))
server.listen()
conn,addr=server.accept()
count=10
while count:
data=conn.recv(1024)
print(data.decode("utf-8"))
conn.send(data)
count-=1
server.close()
#客户端
import socket
client=socket.socket()
client.connect(("localhost",8888))
while True:
chioce=input(">>").strip()
client.sendall(chioce.encode("utf-8"))
data=client.recv(1024)
if not data:
break
print(data.decode("utf-8"))
client.close()
最新文章
- 通过Class获取标签,兼容的几种思路
- 如何防止ElasticSearch集群出现脑裂现象(转)
- javascript数据结构和算法[转]
- 在windows上缓存git 密码
- SQL SERVER 常用知识整理
- OpenCV——PS滤镜,毛玻璃特效
- 转载:Keytool 工具介绍
- jquery 防止当前页面被Iframe嵌套,防止登录页面Iframe被嵌套
- mactype配置
- 【golang-GUI开发】项目的编译
- 利用referer属性,记录百度搜索跳转参数
- ABP 权限拦截 第二篇
- Spring Boot 中配置文件application.properties使用
- mac OS 安装maven遇到问题e45: 'readonly' option is set
- docker push images login -u harbor 问题记录 https 证书
- 1.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)——清屏
- IdentityServer4结合AspNetCore.Identity实现登录认证踩坑填坑记录
- Asp.NET MVC 之 调试访问 webservice 时出现“ 无法找到资源 ”的错误
- Python标准库笔记(3) — datetime模块
- scrapy 元素的相对xpath
热门文章
- 关于hover与after,before已及first-letter,first-line的联用
- Promise的使用
- Django用websocket实现聊天室之筑基篇
- springboot项目创建,及运行
- 42-volume 生命周期管理
- MySQL中if的写法
- NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver ...
- bzoj 5218: [Lydsy2017省队十连测]友好城市
- php 交换值
- Python 相对路径和绝对路径--python实战(九)