网络编程基础【day09】:通过socket实现简单ssh客户端(三)
本节内容
1、概述
2、socket发送中文
3、重复发送和多次接收
4、模拟ssh客户端
一、概述
本篇博客讲一下,如果socket客户端断了,另外的客户端怎么接入服务端,还有模拟ssh的链接等。
二、socket发送中文
因为在python 3中只能接受bytes类型的数据,bytes类型只能接受ASCII码里面的数据类型。因为bytes类型是一个ASCII 0-255的数字组合。所以在客户端向服务端传中文时一定要先转成bytes类型,也就是encode(),接收方需要解码,也就是decode()才能识别中文。
2.1、发送中文代码
①客户端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import socketclient = socket.socket()client.connect(("localhost",6969))msg = "小高最帅了"client.send(msg.encode()) #传中文至服务端,需要先编码server_data = client.recv(1024)print("recv:",server_data) #未解码print("recv:",server_data.decode()) #解码client.close()#输出recv: b'\xe5\xb0\x8f\xe9\xab\x98\xe6\x9c\x80\xe5\xb8\x85\xe4\xba\x86' #bytes类型recv: 小高最帅了 #字符串 |
②服务端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import socketsever = socket.socket()sever.bind(("127.0.0.1",6969)) #绑定ip地址和端口sever.listen() #监听conn,address = sever.accept() #获取接收实例和ip地址print("电话来了")client_data = conn.recv(1024) #接收客户端数据print("recv:",client_data)print("recv:",client_data.decode())conn.send(client_data) #发送给客户端sever.close()#输出电话来了recv: b'\xe5\xb0\x8f\xe9\xab\x98\xe6\x9c\x80\xe5\xb8\x85\xe4\xba\x86' #bytes类型recv: 小高最帅了 #解码后的结果 |
注意了:所有的数据发送和接收都用bytes类型就可以了,省的有什么异常情况。
三、重复发送和多次接收
上面的代码只能客户端只能发送一次,服务端接收一次,就这么结束了,感觉很不爽,那怎么实现客户端发送多次,服务端接收多次呐?
3.1、重复发送和多次接收代码
①客户端
说明:客户端在发送处设置死循环(while True),实现重复发送。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import socketclient = socket.socket()client.connect(("localhost",6969))while True: #进入死循环,设置无限次发送 msg = input(">>>:") client.send(msg.encode()) data = client.recv(1024) print("recv:",data.decode())client.close() |
②服务端
说明:服务端在接收时,设置死循环,实现重复接收。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import socketsever = socket.socket()sever.bind(("127.0.0.1",6969))sever.listen()conn,address = sever.accept() #接收连接实例print("电话来了")while True: #设置死循环,接收多次 data = conn.recv(1024) print("recv:",data.decode()) conn.send(data)sever.close() |
注:这边注意了,在服务端,while True千万不能写在conn,address = sever.accept()前面,这个是为什么呢?因为客户端跟服务端只能实现建立一个连接,如果你把while True放在前面,则服务端接收数据后,又要重新建立一个新的等待连接,这样,客户端和服务端都会卡主。
服务端的代码如下:

表现现象:


3.2、处理多个链接
说明:我们在客户端一起链接服务端,我们都知道,一个服务端只能跟一个客户端进行链接通信,那如果说,我这个正在通信的客户端断开跟服务端的通信,那其他的某个客户端就能跟客户端正常通信了,这个实验一定要在Linux服务器上去完成,因为在Windows上就是只要客户端一断开,服务端就断开了。
跟上面一样,客户端的代码没有变,我们现在来变一下服务端的代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import socketsever = socket.socket()sever.bind(("127.0.0.1",6969))sever.listen()while True: #在建立连接之前加一个死循环 conn,address = sever.accept() print("电话来了") count = 0 #加一个计数器 while True: data = conn.recv(1024) if not data:break #这边如果接受客户端数据为空,则重新建立连接 print("recv:",data.decode()) conn.send(data) count += 1sever.close() |
注意:上面if not data:break这段代码不写的后果是:当客户端断开链接时,服务端进入死循环,不断接收客户端的空数据。
现象如图:
①客户端

②服务端

3.3、 客户端发送数据为空
说明:我们之前演示都是客户端输入内容,服务端给出相应,那客户端输入的是空的话,服务端会有什么反映呐?
客户端代码如图:

服务端代码跟上面的一样,执行结果如下:
客户端:

服务端:

原因是:客户端输入的为空,服务端还一直以为客户端在send,然后都卡主了。
那代码怎么改进呢?代码改进如下:
客户端代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import socketclient = socket.socket()client.connect(("localhost",6969))while True: msg = input(">>>:") if len(msg) == 0:continue #这边判断输入的字符是否为空,为空就跳过 client.send(msg.encode()) data = client.recv(1024) print("recv:",data.decode())client.close() |
表现现象:
客户端:

服务端:

四、模拟ssh客户端
4.1、模拟ssh访问
说明:以下代码,是在Linux下环境,而且还是python2.7的环境,如果是python 3的话,需要编码和解码。
①客户端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#! /usr/bin/env python# -*- coding:utf-8 -*-import socketclient = socket.socket()client.connect(("localhost",6969))while True: msg = raw_input(">>>:") if len(msg) == 0:continue client.send(msg) data = client.recv(1024) print(data)client.close() |
②服务端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#! /usr/bin/env python# -*- coding:utf-8 -*-import socket,os #导入os模块sever = socket.socket()sever.bind(("127.0.0.1",6969))sever.listen(5) #最大允许有多少个链接while True: conn,address = sever.accept() print("电话来了") count = 0 while True: data = conn.recv(1024) if not data:break res = os.popen(data).read() #调用linux命令 conn.send(res) #执行的命令返回值sever.close() |
注:conn.send(res)这边如果需要发送全部的话,需要conn.sendall(res)
4.2、下载文件
①客户端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import socketclient = socket.socket()client.connect(("localhost",6969))while True: msg = input(">>>:") if len(msg) == 0:continue client.send(msg.encode()) data = client.recv(1024000) #这边设置的大一点,防止文件的内容接收不到 with open("test_put","wb") as test_put_file: #把下载下来的内容写入到文件中 test_put_file.write(data)client.close() |
②服务端
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import socketsever = socket.socket()sever.bind(("127.0.0.1",6969))sever.listen()conn,address = sever.accept()print("电话来了")while True: data = conn.recv(1024) if not data: print("数据为空") break with open("test","rb") as test_file: all_data_bytes = test_file.read() #读取需要下载的文件,发送给客户端 conn.sendall(all_data_bytes)sever.close() |
注意:这边客户端的接收时有限制的,如果超出了客户端的限制,客户端只接收自己的一部分,而剩余的会在还是在缓冲去,下一次服务端再send的时候,不会发新数据,先把缓冲区剩下的数据发送到客户端。
如图:

网络编程基础【day09】:通过socket实现简单ssh客户端(三)的更多相关文章
- 第1章 网络编程基础(3)——基本Socket通信
服务器常用模型
- python学习之路---day25( 网络编程基础和初识socket)
基本网络知识和初识socket一:基本知识 网线:传输电信号 集线器:将所有连接到集线器的网络设备连通起来 交换机: 升级版的集线器 网卡:接受电信号 MAC地址:物理地址: 8C-88-4B-88- ...
- 网络编程基础——System.Net.Socket 命名空间及相关类的使用
System.Net.Socket 命名空间主要提供制作 Socket 网络应用程序的相关类.(Socket 类.TcpClient 类.TcpListener 类 和 UdpClient 类) 1. ...
- 第5章 Linux网络编程基础
第5章 Linux网络编程基础 5.1 socket地址与API 一.理解字节序 主机字节序一般为小端字节序.网络字节序一般为大端字节序.当格式化的数据在两台使用了不同字节序的主机之间直接传递时,接收 ...
- Android 网络编程基础之简单聊天程序
前一篇讲了Android的网络编程基础,今天写了一个简单的聊天程序分享一下 首先是服务端代码: package com.jiao.socketdemo; import java.io.Buffered ...
- python全栈开发从入门到放弃之socket网络编程基础
网络编程基础 一 客户端/服务器架构 1.硬件C/S架构(打印机) 2.软件C/S架构 互联网中处处是C/S架构 如黄色网站是服务端,你的浏览器是客户端(B/S架构也是C/S架构的一种) 腾讯作为服务 ...
- Linux高并发网络编程开发——10-Linux系统编程-第10天(网络编程基础-socket)
在学习Linux高并发网络编程开发总结了笔记,并分享出来.有问题请及时联系博主:Alliswell_WP,转载请注明出处. 10-Linux系统编程-第10天(网络编程基础-socket) 在学习Li ...
- C#网络编程基础知识
C#网络编程基础知识一 1.IPAddress类 用于表示一个IP地址.IPAddress默认构造函数 public IPAddress(long address);一般不用 其中Parse()方法最 ...
- 用Netty开发中间件:网络编程基础
用Netty开发中间件:网络编程基础 <Netty权威指南>在网上的评价不是很高,尤其是第一版,第二版能稍好些?入手后快速翻看了大半本,不免还是想对<Netty权威指南(第二版)&g ...
随机推荐
- Gedit浏览器常用快捷键备注
此处只记录常用的,而通常意义上的应知应会不做汇总 搜索 : Ctrl +F : 查找字符串 Ctrl + G : 查找字符串的下一实例 Ctrl + Shift + G : 查找字符串的前一实例 Ct ...
- setTimeout运行机制简要理解
经典例子辅助理解setTimeout工作原理 运行结果: 约1秒后输出:1,再过约1秒后输出:2,接着才立即输出:时间流逝了: 2002 毫秒最后输出:时间又流逝了: 2003 毫秒 在现有浏览器环境 ...
- Lambda 动态表达式(排序)
网上看到的: class Program { static List<User> list = new List<User>() { new User(){ID=1,Name= ...
- LOJ2269 [SDOI2017] 切树游戏 【FWT】【动态DP】【树链剖分】【线段树】
题目分析: 好题.本来是一道好的非套路题,但是不凑巧的是当年有一位国家集训队员正好介绍了这个算法. 首先考虑静态的情况.这个的DP方程非常容易写出来. 接着可以注意到对于异或结果的计数可以看成一个FW ...
- MT【279】分母为根式的两个函数
函数$f(x)=\dfrac{3+5\sin x}{\sqrt{5+4\cos x+3\sin x}}$的值域是____ 分析:注意到$f(x)=\sqrt{10}\dfrac{5\sin x+3}{ ...
- 【转】STM32三种启动模式
@2018-12-16 [小记] STM32 启动区域 STM32三种启动模式 借助上述文章理解官方文档<一种从用户代码调用系统存储器中 Bootloader 的方法 >
- BZOJ2801/洛谷P3544 [POI2012]BEZ-Minimalist Security(题目性质发掘+图的遍历+解不等式组)
题面戳这 化下题面给的式子: \(z_u+z_v=p_u+p_v-b_{u,v}\) 发现\(p_u+p_v-b_{u,v}\)是确定的,所以只要确定了一个点\(i\)的权值\(x_i\),和它在同一 ...
- LVS搭建负载均衡(一)NAT模型
应用场景:LVS配置负载均衡方式之一:nat 测试环境: 测试步骤: 1. 在主机lvs上安装ipvsadm lvs~]# yum install ipvsadm -y lvs~]# ipvsadm ...
- 选做题:设计并实现一个Book类
目录 题目分析 设计思路 具体代码 测试代码 运行截图 参考资料 题目分析 题目内容 0.设计并实现一个Book类,定义义成Book.java,Book 包含书名,作者,出版社和出版日期 1.这些数据 ...
- (三)flask中的请求钩子函数
请求勾子 在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要处理,比如: 在请求开始时,建立数据库连接: 在请求开始时,根据需求进行权限校验: 在请求结束时,指定数据的交互格式: 为了让每个视图 ...