D08——C语言基础学PYTHON

语言基础学习PYTHON——基础学习D08 20180829内容纲要:     socket网络编程   1 socket基础概念   2 socketserver   3 socket实现简单的SSH服务器端和客户端   4 粘包   5 小结   6 练习 0 我是小白 先认识一些关键词: TCP(Transmission Control Protocol传输控制协议)是一种面向连接的、可靠的、基于字节流的传输层通信协议, 由IETF的RFC 793定义。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能,用户数据报协议(UDP)是同一层内另一个重要的传输协议。 SSH(SecureShell 。安全外壳协议)由IETF的网络工作小组所指定;SSH为建立在应用层和传输层基础上的安全协议。 SSH是目前较为可靠,专为远程登录会话和其他网络服务提供安全的协议,利用SSH协议可以有效防止远程管理过程中的信息泄露问题,SSH最初是UNIX系统上的一个程序,后来又迅速扩展到其他操作平台。SSH在正确使用时可弥补网络中的漏洞。SSH客户端适用于多种平台。几乎所有UNIX平台—包括HP-UX、Linux、AIX、Solaris、DigitalUNIX、Irix,以及其他平台,都可运行SSH。 FTP(FileTransfer Protocol。文件传输协议) 是 TCP/IP 协议组中的协议之一。 FTP协议包括两个组成部分,其一为FTP服务器,其二为FTP客户端。 其中FTP服务器用来存储文件,用户可以使用FTP客户端通过FTP协议访问位于FTP服务器上的资源。 在开发网站的时候,通常利用FTP协议把网页或程序传到Web服务器上。此外,由于FTP传输效率非常高,在网络上传输大的文件时,一般也采用该协议。 1 socket基础概念 socket的英文原义是“孔”或“插座”。作为4BDS UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄。 socket本质上就是在2台网络互通的电脑之间,架设一个通道,两台电脑通过这个通道来实现数据的互相传递。 网络通信都是基于 ip+port 方能定位到目标的具体机器上的具体服务,操作系统有0-65535个端口,每个端口都可以独立对外提供服务 如果 把一个公司比做一台电脑 ,那公司的总机号码就相当于ip地址, 每个员工的分机号就相当于端口, 你想找公司某个人,必须 先打电话到总机,然后再转分机 。 建立一个socket必须至少有2端, 一个服务端,一个客户端, 服务端被动等待并接收请求,客户端主动发起请求, 连接建立之后,双方可以互发数据。 话不多先来看一段最简单的代码: 服务器端: Socket( ):第一步创建一个 socket 对象,这是用来封装 TCP/IP的过程,之后就可以利用它来发送 TCP 或者是 UDP. e.g. s = socket.socket( ) bind( ):第二步是绑定 IP 和端口,它接受一个元组类型的数据。e.g. s.bind(('127.0.0.1',8088,)) listen( ):第三步是定义最多能挂起的数目,e.g. s.listen(2),意思说你当前允许一个客户端在连接,两个客户端在等待发送消息(挂起)。 accept( ):第四步是创建客户端和服务端之间的那条连接 conn,程序在连接前会处于挂起的状态。 e.g. conn, addr = s.accept( ) 客户端: Socket( ):第一步创建一个 socket 对象,这是用来封装 TCP/IP的过程,之后就可以利用它来发送 TCP 或者是 UDP. e.g. s = socket.socket( ) connect( ):第二步客户端用自己的对象来连接服务端,它接受一个元组类型的数据。e.g. s.connect(('127.0.0.1',8088,)) socket_server(基础版) socket_client(基础版) 接下来依次启动服务器端和客户端: 先启动服务器端: 再启动客户端: 再看服务器端接收了什么? 这么看来基本的功能已经实现了。那么这有没有什么漏洞呢?在执行一次客户端试试看? 这是因为现在还只能接收一个,不能实现并发。c面会有学习。别急慢慢来~而且只能发送一条指令,接收一条指令,这能干毛线啊? 磨刀不误砍柴工,先来看一些基础:关于server =socket.socket() Socket Families(地址簇)   socket.AF_UNIX unix本机进程间通信   socket.AF_INET IPV4    socket.AF_INET6 IPV6 Socket Types   socket.SOCK_STREAM #for tcp   socket.SOCK_DGRAM #for udp   socket.SOCK_RAW #原始套接字。利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。 那么,现在对上面的代码开始进行优化:只能收发一条但是能够实现多用户收发。 服务器端 客户端 通过运行结果可以发现,每个客户端只能像服务器发送一条数据,下条会自动挂起,因为这个时候服务器在等待第二个响应。 那么接下来怎么再次优化呢?一个用户可以多次收发,但不支持多用户同时收发。 只需要对服务器端进行修改即可: 服务器端 问题又来了,不能支持多用户,如果先断开,那第二个客户端能不能连进来呢?不能 服务器端改进 当客户端断开时可以通过捕获异常让程序正常进行。这样才能继续接收第二个。 2 socketserver The socketserver module simplifies the task of writing network servers. There are five classes in an inheritance diagram, four of which represent synchronous servers of four types: 主要介绍TCPserver: class socketserver.TCPServer(server_address, RequestHandlerClass, bind_and_activate=True) This uses the Internet TCP protocol, which provides for continuous streams of data between the client and server. If bind_and_activate is true, the constructor automatically attempts to invoke server_bind() andserver_activate(). The other parameters are passed to the BaseServer base class. 创建一个socketserver步骤: 1 first,you must create a request handler class by subclassing the BaseRequestHandler class and overrinding(覆盖) its handle() method ;    this method will process incoming request.    你必须创建一个请求处理类,并且这个类要继承BaseRequestHandler,并且还要覆盖父类里的handle() 2 second, you must instantiate one of the server classes, passing its server's address and the request handler class.   你必须实例化TCPServer,并且传递server ip和上面创建的请求处理类传给TCPServer。 3 third, call the handle_request() or server_forever() method of the server object to process one or many requests.   server.handle_request() #只处理一个请求   server.handle_forever() #处理多个请求,永远执行 4 finally, call server_close() to close the socket. 那么接下来就创建一个socketserver: Socketserver Client 此时,能不能支持多并发呢?我们可以多次启动客户端,发现不能。只有先断开1才会执行2,断开2才会执行3。 那么如何实现多并发呢?其实很简单。 只需要在服务器端修改TCPServer为ThreadingTCPServer即可。 ThreadingTCPServer就是多线程。什么事多线程呢?看后续 3 socket实现简单的SSH服务器端和客户端 通过os模块调用命令行。 SSH服务器端 SSH客户端 当使用存在的指令时,会有正常输出,但是当指令不存在时,通过判断让程序正常进行了。这个以后会有更好的解决办法 可以通过以下几个指令试一下,看一下执行结果 dir  pwd  ipconfig 运行结果会发现竟然不全,那究竟是为什么呢?客户端接收1024剩下存在服务器端的内存里,就一直存在缓冲区中,如果不接收完会影响下一条指令的正常输出。 那么怎样能够接收完呢? 思路是这样的,在服务器端发送给客户端时先判断数据大小,客户端接收数据大小之后,可以通过循环每次1024接收,直至传输完毕。 修改之后代码是这样的。可以试试对比一下有什么不同?再次执行ipconfig SSH服务器端 SSH客户端 我们看一下服务器中的一段代码: 两次发送,系统有时会把它们合在一起发出去,就出现了粘包~!因为不知道缓冲区什么时候会把这两条命令放在一起。 那下面来了解一下粘包。 4 粘包 TCP粘包是在一次接收数据不能完全地体现一个完整的消息数据。TCP通讯为何存在粘包呢? 主要原因是TCP是以流的方式来处理数据,再加上网络上MTU的往往小于在应用处理的消息数据,所以就会引发一次接收的数据无法满足消息的需要,导致粘包的存在。 那么我们如何解决呢? 第一种解决方法: 首先通过一种缓冲区接收数据超时,发送命令来间隔两次命令传输,但这样的后果就是延长数据传输时间,降低了传输效率。 这种方法显然不太可取。太low了~! 下面来个正确姿势解决粘包: 第二种解决方法: 让客户端给服务器端一个确认指令,通过确认指令间隔两次命令传输,这样就能阻隔两次命令的粘包。 服务器端 客户端 第三种方法: 通过服务器发送给客户端需要接受数据的大小,然后客户端自己判断大小通过每次接1024,最后一次把剩下的接收。也就是说刚好接受文件大小,再继续接受下一个。 这样也能解决粘包问题。同时下面的代码中对文件的传输还进行了MD5加密。关于ftp ftp server:   1 读取文件名   2 检测文件是否存在   3 打开文件   4 检测文件大小   5 发送文件大小给客户端   6 等待客户端确认   7 开始边读边发数据   8 发送md5 ftp服务器端 ftp客户端 5 小结 真的不懂,可能以后会明白的。 安慰别人的话说服不了自己。 间歇性踌躇满志,持续性混吃等死~! 6 练习 作业:开发一个支持多用户在线的FTP程序 要求: 用户加密认证 允许同时多用户登录 每个用户有自己的家目录 ,且只能访问自己的家目录 对用户进行磁盘配额,每个用户的可用空间不同 允许用户在ftp server上随意切换目录 允许用户查看当前目录下文件 允许上传和下载文件,保证文件一致性 文件传输过程中显示进度条 附加功能:        新建目录mkdir       .查看当前工作目录的路径pwd 如果对一些基础概念还不够明确,或者这篇博客的逻辑不过清晰,可以看这里 python之socket_ssh实例  http://www.cnblogs.com/0zcl/p/6017088.html python之socket_ftp实例  http://www.cnblogs.com/0zcl/p/6022774.html 6.1 程序目录结构 服务器端 客户端 都看到这里了,如果真的想弄明白,那就看这篇博客吧,我自己也不会。以后看明白了再补上。说出这句话自己心里都没底气。 点击这里:https://www.cnblogs.com/0zcl/p/6259128.html 我是尾巴~ 这次推荐:以后买来新电脑请看这篇文章:https://mp.weixin.qq.com/s/OAQ3Vn3NRRHE4IfzoONjng 可以说是非常用心了!https://www.cnblogs.com/zhangkanghui/p/9551947.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信