【深入理解】Python网络编程

一些网络知识

啥是DDOS攻击(洪水攻击),就是一些机器通过伪造IP地址头,不断的去访问(攻击)一个网站,导致网站的崩溃的现象,一个网站能接受的并发量是有限的,通过洪水攻击,十几台机器大量伪造IP地址,就可以搞垮一个网站,所以大企业要建立大规模的集群。

什么是socket

socket又叫套接字,我们的网络通信比如HTTP,FTP,ssh他们都要接收数据和发送数据的过程,我们把这个接收数据的过程和发送数据的过程封装起来就是socket,通常我们用一个Socket表示“打开了一个网络链接”

socket内置的方法

socket.socket:声明socket类型,并创建socket对象
socket.bind((‘127.0.0.1’,80)):绑定端口,必须注意这里是一个元组,IP地址使用字符串的形式写入元组
socket.listen(5):监听端口,可以设置一个最大连接数,最多可以设置多少个连接
server.accept():接受连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。接收TCP 客户的连接(阻塞式)等待连接的到来,这个函数用来表示一个等待的状态
server.close:关闭套接字
sc.recv(bufsize[,flag])
接受套接字的数据。数据以字符串形式返回,bufsize指定最多可以接收的多少字节。flag提供有关消息的其他信息,通常可以忽略。
sc.send(string[,flag]):
将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。即:可能未将指定内容全部发送。
sc.sendall() :就是简单的循环send
socket.gethostname():获取本地主机名

一个简单的socket案例

服务端代码:

#!/usr/local/bin/python3
#coding:utf-8
"""思路:
1.服务端先import socket
2.创建socket并连接
2.进行端口的绑定,使用bind,传一个元组进去
4.监听端口
5.等待连接
6.接收到数据
7.发送数据
"""
import socket
server = socket.socket()  # 声明socket类型,同时生成socket连接对象
server.bind(('127.0.0.1', 9999))  # 绑定端口
server.listen(5)  #
# 监听端口,参数可以设置最多连接数,也就是最多可以挂起多少个连接
print('我要开始等电话了')
conn, addr = server.accept()
# server.accept()会返回两个值,一个是标志位,一个是地址位
# cron是客户端连过来而在服务端为其生成的一个实例
print("电话来了")
# 听电话
data = conn.recv(1024)  # recv的大小是有限制的,不能一次性都接收过来
print("recv:", data)
conn.send(data.upper())  # send的时候不能send为空,不然就会一直卡在这里
server.close()

客户端代码

#!/usr/local/bin/python3
#coding:utf-8
# 实现网络编程,思路是
"""
1.先创建socket连接,
2.发送数据
3。接收数据
"""
import socket
client = socket.socket()    # 创建socket类型,同时生成socket连接对象
client.connect(('127.0.0.1', 9999))  # 连接这里必须是一个元组
client.send(b"hello")  
# 以bytes类型发送,Python3不能直接发字符串,Python2都可以
data = client.recv(1024)  
# 设置接收1k的数据,在centos里面设置很大都不会报错,但是Ubuntu会
print(data)
client.close()

改进上面的代码,实现一直在互相通信
客户端

import socket

client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))

while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode("utf-8"))
    data = client.recv(10240)
    print("recv:",data.decode())

client.close()

服务端

import socket

client = socket.socket() #声明socket类型,同时生成socket连接对象
client.connect(('localhost',6969))

while True:
    msg = input(">>:").strip()
    if len(msg) == 0:continue
    client.send(msg.encode("utf-8"))
    data = client.recv(10240)
    print("recv:",data.decode())

client.close()

这个好像没啥意思,但是依赖这些基础可以做个ssh工具或者FTP。

socket粘包的概念

1.“粘包”, 即服务器端你调用时send 2次,但你send调用时,数据其实并没有立刻被发送给客户端,而是放到了系统的socket发送缓冲区里,等缓冲区满了、或者数据等待超时了,数据才会被send到客户端,这样就把好几次的小数据拼成一个大数据,统一发送到客户端了,这么做的目地是为了提高io利用效率,一次性发送总比连发好几次效率高嘛。 但也带来一个问题,就是“粘包”,即2次或多次的数据粘在了一起统一发送了。
2. 解决粘包的问题:我们可以在两次send之间加上一个recv()来接收确认信息,然后在另一方发送确认信息,conn.recv()会一直等待客户端发个确认信息过来,这样避免粘包,我们也可以让程序sleep(0.5)秒来避免,但是会降低程序性能,这是一种比较笨的方法。

socketserver(进阶)

socketserver是socket的再封装,socket无法支持多用户,而socketserver支持多用户多并发。
使用socketserver的步骤

  1. 首先必须自己创建一个请求处理类,这个类要继承自BaseRequestHandle,然后重写父类的handle方法。
  2. 实例化TCPServer,然后传递server_ip和我们创建的请求处理类作为参数给TCPServer
  3. 调用server.handle_request():只能处理一次
    调用server.serve_forever()可以处理多次。
  4. Finally, call server_close()to close the socket.

在这里插入图片描述
注意

  • handle()函数里面处理与客户端的交互
  • 在handle里面加循环,不然连一个就会断了
  • 在python3里面,这段代码会抛异常,要注意捕捉异常
开发的过程遇到的坑以及心得

初学网络编程,边学边做,遇到开发的一些巨坑。

  • 开发FTP服务器时,开发切换目录这个功能,不能调用os.system('cd '),这是个大坑,因为os.system每一次调用的时候都会开启一个新的终端来执行命令,当执行完命令,就会把这个终端咔嚓关掉,所以最终目录还是没有切换。所以要使用os.chdir()来切换,但是这个也不太好使,它好使是因为当前用户确实切换目录了,但是你切换的是sockerserver的工作目录,也就是说服务器端的目录根本就没有切换,只是客户端切换了,并且客户端自己ls一下,也发现确实有那个目录下面的东西
  • 使用socketServer的时候要注意想实现多线程必须调用ThreadingTCPServer,调TCPServer还是不能实现多线程的
  • ForkingTCPServer虽然在Linux上可以实现和ThreadingTCPServer一样的效果,但是在Windows上不行,因为两个系统的进程管理方式不一样。
  • ThreadingTCPServer每来一个请求,就会开启一个新的进程来处理请求
  • json的使用,写FTP的时候用过一下,在网络编程里面有时候我们想给接收方发送一个字典,那么可以先把它转化为json格式,然后在encode一下,转成bytes类型,然后接收方接收时先decode一下,在把这个json字符串使用loads方法转为Python的数据类型
  • 在写FTP的时候还用到了刚刚学到的语法:反射(通过字符串去映射到类里面的属性),很nice
待更新
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值