小白学习之路,网络编程(下)

一,socket进阶

在前面的博客中讲到了一些基本的计算机网络知识,有一点也是为我在要考传输与交换看到一个题,然后就看到说ARP属于网络层,因为ARP协议跟网络相关,但是我前面的博客说的是ARP协议属于数据链路层。当时我就呆了,不会讲错了吧,后来查了一下,原来都是可以的,ARP协议有的人说在网络层也行,在数据链路层也行。当然这只是一个小插曲。昨天在讲到socket的几种情况还没解决,这篇文章就跟大家解决。大概有几个问题,一个是每次只能接受一定数据大小的数据,如果数据太大怎么办?还有提到的粘包的问题,还有一个就是只能同时一个客户端连上服务器,其他服务器都要等着。

1,先用socket实现一个简单的ssh

ssh服务端

 1 import socket,os
 2 server=socket.socket()
 3 server.bind((‘127.0.0.1‘,1314))
 4 server.listen()
 5 while True:
 6     conn,addr=server.accept()
 7     try:
 8         while True:
 9             data=conn.recv(1024)
10             print(‘客户端发来的命令是:‘,data.decode())
11             if not data:break
12             if len(data)==0:
13                 print(‘命令为空‘)
14             send_data=os.popen(data.decode()).read()#执行命令,并读出结果
15             conn.send(send_data.encode())
16     except ConnectionResetError as e:
17         print(‘一个客户端断开连接‘)
18     conn.close()
19 server.colse()

ssh客户端

 1 import socket
 2 client=socket.socket()
 3 client.connect((‘127.0.0.1‘,1314))
 4 while True:
 5     data=input(‘>>>‘)
 6     if len(data)==0:continue
 7     client.send(data.encode())
 8     recv_data=client.recv(1024)
 9     print(recv_data.decode())
10 client.close()

写好了,忍不住要开始装逼了,于是你在客户端输入了一个dir运行结果如下

>>>dir
 驱动器 E 中的卷是 新加卷
 卷的序列号是 CA7D-FFB5

 E:\zzq_python\博客 的目录

2018/06/29  15:49    <DIR>          .
2018/06/29  15:49    <DIR>          ..
2018/06/24  22:36             1,709 calculator.py
2018/06/26  09:34             1,048 deal_error.py
2018/06/28  18:08               349 socket_client.py
2018/06/28  18:06               453 socket_server.py
2018/06/29  15:47               253 ssh_client.py
2018/06/29  15:49               613 ssh_server.py
2018/06/26  16:50             1,508 单例模式.py
2018/06/26  10:22               454 接口类.py
               8 个文件          6,387 字节
               2 个目录 60,092,284,928 可用字节

但是想了想不得行,这个还不够啊,于是你查了一些你电脑的ip地址,运行结果就不贴出来了。你会惊奇的发现,怎么回事啊。为什么没有显示完呢。仔细想了想,出现前面提到的问题了,每次接收只能接收固定长度的数据,但是超出了只有在下一次接收的时候接收了,那肯定是不行的啊,这种情况,那也太low了吧。于是为了解决这种问题,我们可以先发一个文件的长度,然后客户端接收到以后,根据接收的文件长度跟实际长度比较,知道收完为止。emmm,带着这种想法,我们就来试试实现吧。

2,升级版ssh

ssh服务端

 1 import socket,os
 2 server=socket.socket()
 3 server.bind((‘127.0.0.1‘,1314))
 4 server.listen()
 5 while True:
 6     conn,addr=server.accept()
 7     try:
 8         while True:
 9             data=conn.recv(1024)
10             print(‘客户端发来的命令是:‘,data.decode())
11             if not data:break
12             if len(data)==0:
13                 print(‘命令为空‘)
14             send_data=os.popen(data.decode()).read()#执行命令,并读出结果
15             data_len=len(send_data.encode())
16             print(‘发送的数据总长度:‘,data_len)
17             conn.send(str(data_len).encode())
18             print(conn.recv(1024).decode())
19             conn.send(send_data.encode())
20     except ConnectionResetError as e:
21         print(‘一个客户端断开连接‘)
22     conn.close()
23 server.colse()

ssh客户端

 1 import socket
 2 client=socket.socket()
 3 client.connect((‘127.0.0.1‘,1314))
 4 while True:
 5     data=input(‘>>>‘)
 6     if len(data)==0:continue
 7     client.send(data.encode())
 8     data_len=client.recv(1024).decode()
 9     client.send(‘接收到数据长度了‘.encode())
10     get_len=0#设置最开始长度为0
11     get_data=b‘‘
12     while get_len<int(data_len):
13         data=client.recv(1024)#接收的数据
14         get_len+=len(data)#接收的长度
15         get_data+=data
16     print(‘数据长度为:‘,data_len,get_data.decode())
17 client.close()

当然有的人会对这个代码感到疑惑,其中为什么在跟客户端发送完数据长度以后,不直接发送数据内容,中间要接收客户端发来的接收数据长度成功,很多人会觉得这是累赘,但是如果你连续两次发送,这种情况就有可能会出现粘包现象,为了解决这个问题,所以在中途增加了一个接收客户端的信息。讲到这里就解决了两个问题了,一个数据过长,一个粘包的问题,还有一个问题就是不能存在多客户端同时跟服务端交互的问题。

3,实现文件传输

在前面的一个ssh做基础的情况下,我们是不是也能跟ftp一样传文件这些呢,当然可以肯定的告诉你,可以传文件的,而且在后面的学习完成以后,你还能自己写一个ftp实现上传下载文件的功能。先做一个简单的文件传输功能吧。

服务端(server)

 1 import socket,os
 2 server=socket.socket()
 3 server.bind((‘127.0.0.1‘,1314))
 4 server.listen()
 5 while True:
 6     conn,addr=server.accept()
 7     print(‘连接成功!‘)
 8     try:
 9         while True:
10             file_name=conn.recv(1024).decode()
11             if not file_name: break
12             if os.path.isfile(file_name):#判断文件是否存在
13                 file_len=os.stat(file_name).st_size#获取文件大小
14                 conn.send(str(file_len).encode())
15                 conn.recv(1024)
16                 with open(file_name,‘rb‘) as f:
17                     for i in f:
18                         conn.send(i)
19                 print(‘文件发送完成‘)
20             else:
21                 print(‘文件不存在‘)
22     except ConnectionResetError:
23         print(‘一个客户端断开‘)
24     finally:
25         conn.close()
26 server.close()

客户端(client)

 1 import socket
 2 client=socket.socket()
 3 client.connect((‘127.0.0.1‘,1314))
 4 while True:
 5     file_name=input(">>>")
 6     if len(file_name)==0:continue
 7     client.send(file_name.encode())
 8     file_len=client.recv(1024).decode()
 9     client.send(‘接收数据长度成功‘.encode())
10     get_len=0
11     f=open(file_name,‘wb‘)
12     while get_len<float(file_len):
13         data=client.recv(1024)
14         get_len+=len(data)
15         f.write(data)
16         print(‘已经完成‘,get_len,‘/‘,file_len)
17     print(‘文件传输完成‘)
18     f.close()
19 client.close()

基本socket的用法就讲完了,当然在使用文件传输的时候,最好是用前面学习的hashlib模块进行文件内容的加密,这里就不写了,感兴趣可以试着写一写,在学习文件传输以后,就可以写一个简单的ftp了。能够实现文件的上传和下载了,上传就是跟下载相反。不过还是不能实现多个客户端同时与服务端交互。下面的这个socketserver就很好的解决了这个问题。

二,socketserver用法

前面都是为最后面的装逼做铺垫的,没错的,下面即将进入的是我们今天的装逼操作了,socketserver。

当然这里我们也只是写简单的用法,其实用法跟socket用法是差不多的,所以只给了简单的使用方法

服务端(server)

 1 import socketserver
 2 class MyServer(socketserver.BaseRequestHandler):
 3     def handle(self):#里面是跟客户端交互的全过程
 4         while True:
 5             try:
 6                 data=self.request.recv(1024) #self.request相当于socket里面的conn
 7                 print(‘收到来自客户端%s的消息:%s‘ %(self.request,data.decode()))
 8                 self.request.send(data.upper())
 9             except ConnectionResetError as e:
10                 print(‘error:‘,e)
11                 break
12 if __name__ == ‘__main__‘:
13     #创建一个服务,绑定ip跟端口
14     server=socketserver.ThreadingTCPServer((‘127.0.0.1‘,1314),MyServer)
15     server.serve_forever()#服务一直开启

客户端(client)

1 import socket
2 client=socket.socket()
3 client.connect((‘127.0.0.1‘,1314))
4 while True:
5     data=input(‘>>>‘)
6     client.send(data.encode())
7     get_data=client.recv(124)
8     print(get_data.decode())
9 client.close()

这里客户端还是使用的socket的方法,多连接只是相当于服务端来说的。

基本已经学完了网络编程,也能自己实现一个完整的ftp了,虽然有点困难,但是还是推荐自己实现一个,可以加强对代码的熟悉,而且还能练习到前面学习的东西。马上期末了,好多作业要做,还要为期末考试做准备,还要准备毕业设计,还要准备找实习工作。哎,感觉有点难受,最近烦心事也是挺多的。写博客,最开始为了回顾以前学过的知识,把以前自己做的学习笔记从word搬到博客上,现在慢慢也成了自己有时候类似写日记的地方了。挺迷茫的,一个啥子都不会的大学生,周围优秀的人越来越优秀,不过还好有你陪我,你教会了我挺多的,希望我付出的努力以后能给你带来幸福。

原文地址:https://www.cnblogs.com/zzqit/p/9245438.html

时间: 2024-11-13 03:52:23

小白学习之路,网络编程(下)的相关文章

《Python学习之路 -- 网络编程》

在前面已经提到过,互联网的本质就是一堆协议,协议就是标准,比如全世界人通信的标准是英语,所有的计算机都学会了互联网协议,那么所有的计算机就可以按照统一的标准去收发信息完成通信了. 作为普通开发人员的我们,写的软件/程序都是处于应用层上的,然而,想要让软件接入互联网,就必须得通过传输层,也就是必须遵循TCP协议或者UDP协议.这是两个非常复杂的协议,如果遵循原生的协议,那么必然会大大降低效率,所以就有了socket抽象层的概念.socket是应用层与TCP/IP协议族通信的软件抽象层,它是一组接口

Python学习之路--网络编程

由于不同机器上的程序要通信,才产生了网络 C/S Client/Server 客户端/服务端 服务端 一直运行 等待服务别人 客户端 寻求服务的时候 才请求服务 B/S Browser/Server 浏览器/服务器 b/s架构是c/s架构的一种 实现通信上有全球唯一的MAC地址 网卡和网线 网卡 通过ip地址就能找到对应的MAC地址  ARP协议 交换机 ---- 多台机器之间的通信问题 广播风暴 网关  局域网中的机器想要访问局域网外的机器,需要通过网关访问 IP地址 和 子网掩码 按位与 

python学习之路网络编程篇(第一篇)

新课程知识的引入:python作用域 #python中无块级别作用域 if 1 == 1 : name = 'alex' print(name) for i in range(10): name = i print(name) #python中以函数为作用域 def func(): name = 'alex' print(name) #程序执行结果 # Traceback (most recent call last): # File "D:/PythonS13/Day10/С????1_pyt

python学习之路网络编程篇(第五篇)

paramiko简介 paramiko 是基于Python实现的SSH2远程安装连接,支持认证及秘钥方式.可以实现远程命令执行.文件传输.中间SSH代理等功能. paramiko安装 #!/bin/bash #install indepence package cd /data/soft wget https://www.dlitz.net/pub/dlitz/crypto/pycrypto/pycrypto-2.6.tar.gz yum -y install gcc python-devel

python学习之路网络编程篇(第五篇)-续篇

Python堡垒机实现之基础知识 一般的堡垒机必须要具备以下5个基本功能: 1.权限控制 2.执行命令 3.上传下载文件 4.远程登录 5.记录操作 权限控制 说明:根据不同的登录用户分配不同的可管理的主机组.(再细分的权限就是根据不同的用户控制可在主机上执行的命令,一般不会限制的这么严格) 思路:使用数据库创建用户表,表字段有ID.用户名.密码.所属组,再创建主机表,表字段有ID,主机IP,所属组.其中用户表中的所属组和主机表中的所属组相对应,这样就能把两张表关联起来.当用户登录的时候就可以根

Android开发学习之路--网络编程之xml、json

一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载xampp,然后安装之类的就不再多讲了,参考http://cnbin.github.io/blog/2015/06/05/mac-an-zhuang-he-shi-yong-xampp/.安装好后,启动xampp,之后在浏览器输入localhost或者127.0.0.1就可以看到如下所示了: 这个就

Linux程序设计学习笔记----Socket网络编程基础之TCP/IP协议簇

转载请注明出处: ,谢谢! 内容提要 本节主要学习网络通信基础,主要涉及的内容是: TCP/IP协议簇基础:两个模型 IPv4协议基础:IP地址分类与表示,子网掩码等 IP地址转换:点分十进制\二进制 TCP/IP协议簇基础 OSI模型 我们知道计算机网络之中,有各种各样的设备,那么如何实现这些设备的通信呢? 显然是通过标准的通讯协议,但是,整个网络连接的过程相当复杂,包括硬件.软件数据封包与应用程序的互相链接等等,如果想要写一支将联网全部功能都串连在一块的程序,那么当某个小环节出现问题时,整只

head first c&lt;11&gt;初探网络编程下

上一篇博文可以实现基本的网络通信,但是只能服务给一个人,我们可以通过给每个客户端fork()一个子进程,来实现一对多的服务. 方法: 客户端连到服务器以后,服务器启动一个新创建的套接字对话,也就是说父进程可以继续连接下一个客户端,而子进程来需要处理 accept()创建的副套接字,实现通信功能.父进程克隆子进程后可以关闭副套接字close(connect_d),而子进程可以关闭主监听套接 字close(listener_d). 说了半天就是,一个只负责拉客,一个只负责接客. while(1) {

Qt学习心得之网络编程简单的局域网聊天服务端建立

学而不思则罔,思而不学则殆.学习和思考是相辅相成的,通过这几天对网络编程的学习,收获颇丰.接下来我将利用Qt做的一个以TcpIp协议为传输方式的简单的局域网聊天服务端与大家分享下: 首先谈谈我个人对Tcp协议的理解:Tcp就是网上购物,买家和买家之间的物品传递,快递公司的扮演.快递公司将卖家所要寄出的物品进行包装,给予独特的号码,并从卖家获取目的地地址,得知这些明确信息后准确将物品送到买家,买家签收后,卖家通过快递单号查询到买家签收的消息. 其次是这个简单局域网聊天服务器的创建思路.如下图是思路