python网络通信框架_Python运维-Socket网络编程 (1)

Python socket 简介

在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据

套接字是通信的基石,是支持TCP/IP协议的路通信的基本操作单元。Socket(套接字)可以看成是两个网络应用程序进行通信时,各自通信连接中的端点,这是一个逻辑上的概念。

网络世界一切皆 socket。如果我们精通 socket 又 熟悉 应用层的高层协议. 那我们就可以通过socket连接网络世界中的一切。

黑客不需要网络网络编程知识?框架这么多何必自己实现?

网络一直都是黑客最喜爱的竞技场. 通过简单的网络访问,攻击者可以做到任何事情。例如主机扫描、数据包注入、数据嗅探、远程攻击主机,等等。如果通过某种方式进入了目标企业的内部网络,那么在这个陌生的环境中,你可能会发现主机陷入了某种困境: 你没有任何工具进行网络攻击,没有natcat, 没有wireshark,没有编译器,甚至没有办法安装编译器。然而在很多情况下,你可能会惊讶地发现目标环境中安装了Python,这就是下一步的工作起点, 不仅是黑客, 我们的网络管理员、机房管理员,在某些情况下也会用到。

Python socket 模块可以快速创建 TCP 和 UDP服务器及客户端

TCP 客户端

在渗透测试中我们经常会遇到需要创建一个TCP客户端来连接服务、发送垃圾数据、进行模糊测试或者进行其他任务的情况。多说无益,我们开始编写代码。41f265087483366ff208be5c3b34e1ad8b2d2752.png

① 首先我们创建一个套接字, 你可能会发现我没有使用参数选择协议 AF_INET 和类型 SOCK_STREAM. 因为它默认 AF_INET 表示的IPv4地址, 类型是 SOCK_STREAM说明这是一个TCP客户端。 ② 连接到目标地址和端口, 该方法接受一个元组 (IPAddress, Port) 建立连接失败是回抛出异常,  建立连接成功后我们就可以收发数据了。 ③ 使用 send() 方法发送数据注意是字节流数据, byte, 可以使用 encode() 方法将字符串类型 转为 字节类型。④ 使用 recv() 方法接受数据具体大小根据你传入的参数大小决定。 单位是字节。接受的数据是字节流数据,可以使用 decode() 方法将字节类型转为字符串类型。⑤ 程序不用了就关闭连接

TCP 服务器

用 Python 创建 TCP 服务端和创建客户端一样简单。我们可以绑定到命令行 shell 或者创建一个代理(后续)。加下来我们创建一个TCP服务器1422e1b922c11c38dde971f0f10f968c004f55dc.png

① 绑定监听地址和端口 ② 设置最大挂起连接等待数,③ 接受连接,该方法返回两个结果 远程(客户端)套接字对象, 远程(客户端)连接地址和端口(阻塞方法),④ 接受客户端数据, 注意这里是阻塞的(客户端没法信息就会一直等等到又信息才会往下执行),⑤ 发送数据,该方法也会阻塞如果客户端一直没有接受也会一直阻塞

执行结果

客户端和服务端都编写完成了我们先允许服务端 再允许客户端看一下结果

服务端8e5639e133d56e2a378cf1e68b5fb46d7e25a147.png

客户端5f4a651b8a0d23ccd1b7c22aff924d24a0ad10e9.png

运行没有问题, 他们可以互相通讯了。

问题

运行是可以运行了但是,服务器和客户端一次链接只能交换一次数据,非常不符合现在服务器的标准。可以这么解决呢??? 上面提到有三个阻塞的方法. accept()、send()、recv()。这三个方法都是先等对方有相应的行为才会往下执行。回产生上面问题呢?? 我们一 一解决, 如果中间觉得繁琐可以跳到最终解决方法

解决只能通讯一次(保持连接)

现在的连接叫 短连接,即数据交换完成之后立刻断开连接. 目前在使用短连接的大家都熟悉的 HTTP 通讯协议

客户端92efd98002ab9ceed33378e7e54394c524695828.png

代码逻辑几乎没变, ① while True进入循环 ② 接受用户输入(阻塞方法), ③ 判断用户是否输入 exit() 退出循环, 关闭连接。然后发送数据, 接受响应. 打印响应信息,循环进行。

服务器3493cb4c9e7c8c691cce63cfa04d2e267b24945c.png

大致逻辑也没变, ① 连接成功后进入循环, ② 接受客户端数据 ③ 如果接受到 exit() 退出循环关闭连接。循环操作。

服务端的发送(响应)数据也可以 加上 input监听用户输入, 这样就可以实现 半双工通讯了 即同一时间段只有一边可以发送数据另外一边接受数据。例子: 对讲机

我们来看一下执行结果

客户端522d781955439c51640e4b5d3920e73cd34bc82c.png

服务器3543423232388e39b7839357c0717dda4f557066.png

长连接通讯就完成了, 我们只要不主动断开连接就可以一直交换数据, 但是还存在上面问题呢...

我们来将一下整套程序的流程, 服务器开启监听服务. 客户端连接, 连接成功后 服务器和客户端进入循环, 互相通讯, 直到程序退出 才断开连接。看似没什么问题呀... 但你会发现 第二个人想尝试连接这个服务器时... 连接是没报错 但也没执行到 while True 可以交换信息.

原因是我们的服务器没把 accept 写到循环里(我的意料之外...我也忘记了)如果写道循环里大家想想. accept 是阻塞.. 那就套两层循环. 对套两层循环 下面这样74709d89e168cc8671c274446a824e02d2702078.png

这样就会出现刚刚的问题了 连接上了但是服务器没有处理我的连接, 因为他在处理上一个客户端的连接, 服务器此时处于忙碌状态。

为什么连接成功了呢?因为我们设置了 Listen(5) 最大挂起等待连接数 5, (意思是当服务器忙碌时能有多少台客户端在排队等待). 你把他设低一点, 然后连多几个你就会发现超过数量后会报错。

最终解决

其实还存在我没提及的很多问题.. 例如 同一时间只能一方作为发送端的半双工通讯。我们现在来解决, 我们需要将 recv() 和 send() 方法写成异步非阻塞的就行了。

服务器d723500d855e72737aae36c94ffa54b7e8c9b83d.png

我们借助了多线程是我们的程序达到异步效果. ① 接收到一个连接后, 使用多线程交给 函数 handler_connect处理, 将 conn, addr 传给该函数。② 循环接受数据. 此时是另一个线程在做不会影响主线程 accpet() 继续接受连接

客户端586e90c7f23fcd3e67711fd9b18a07b8a9af135f.png

逻辑和服务器差不多. 我们连接成功后, 开启线程处理服务器响应信息, 循环发送信息. 直到主动退出, 此时服务器就可以同时处理多条连接了b579d37141e0f437ede69c446018d1e49a3d9a23.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值