当前位置: 首页 > news >正文

网络安全编程——TCP客户端以及服务端Python实现

以网络安全工具为脉络,分类解析攻防、检测、防护等各类工具的原理与实操,构建工具应用体系,助力读者掌握工具使用技巧;
今天给大家带来的是TCP客户端以及服务端简单通信的python代码实现;

文章目录

    • 简介
    • 代码实现(第一版—只能实现一次会话)
      • TCP客户端
      • TCP服务端
      • 效果显示
    • 代码实现(第二版—可以实时通信,并由客户端主动结束会话)
      • TCP客户端:
      • TCP服务端:
      • 效果显示:
      • 异常情况:
        • **解决方法(任选一种):**
        • **方法1:更换一个未被占用的端口**
        • **方法2:关闭占用`9990`端口的程序**
    • 总结


简介

今天给大家带来的是TCP客户端以及服务端简单通信的python代码实现,这个专栏文章我会尽量用大白话讲解每一步代码的作用;

代码实现(第一版—只能实现一次会话)

TCP客户端

在渗透测试过程中,经常需要创建一个TCP客户端,用来测试服务、发送垃圾数据、进行fuzz等等。

  • 如果黑客潜伏在某大型企业的内网环境中,则不太可能直接获取网络工具或编译器,有时甚至连复制/粘贴或者连接外网这种最基本的功能都用不了。
  • 在这种情况下,能快速创建一个TCP客户端将会是一项极其有用的能力。

在这里插入图片描述

而通常来说双方通信的基础条件是需要有客户端以及服务端,双方进行通信。所以话不多说,

  • 我们先开始实现TCP客户端的代码:
import sockettarget_host = "127.0.0.1"
target_port = 9990# 创建一个socket项目
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# AF_INET参数表示我们将使用标准的IPv4地址或主机名
# SOCK_STREAM表示这是一个TCP客户端# 建立链接
client.connect((target_host,target_port))# 发送数据
# client.send(b"GET / HTTP/1.1\r\nTell Me:I am your baby!\r\n\r\n" )message = 'Hello World, I want to go HVV.'
client.send(message.encode('utf-8'))# 接收数据
respond = client.recv(1024)print(respond.decode())
client.close()
  • 代码解释:
    • socket.socket(socket.AF_INET,socket.SOCK_STREAM):AF_INET参数表示我们将使用标准的IPv4地址或主机名,SOCK_STREAM表示这是一个TCP客户端;
    • 通过connect()函数进行连接,并send()发送一次数据到服务端;
    • 我们接收到服务端发送的数据后,直接close()关闭连接(不再进行后续的通信,这也是为什么只能进行一次通话的重要原因

TCP服务端

import socket
import threadingip = '0.0.0.0'
port = 9990def main():server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 服务器指定监听的地址与端口server.bind((ip,port))# 让服务器开始监听,(最大等待连接数为5)server.listen(5)print(f'[*] Listening on {ip}:{port}')while(True):client,address = server.accept() # 当连接建立的时候# client:接收到的客户端socket对象# address:远程连接的详细信息print(client)print(address)print(f'[*] Accepted data from {address[0]}:{address[1]}')# 创建一个新的线程,让它指向handle_client函数,并传入client变量client_handler = threading.Thread(target=handle_client,args=(client,))client_handler.start()def handle_client(client_socket):with client_socket as sock:request = sock.recv(1024)print(f'[*] Receive:{request.decode("utf-8")}')sock.send(b'ACK')if __name__ == '__main__':main()
  • 代码解释:
    • server = socket.socket:很简单的道理,既然客户端要建立socket对象,那么服务端自然也是要有相应的服务;
    • server.listen(5):绑定{ip}:{port}后,我们进行listen监听,并等待客户端发送消息;
    • 原理:客户端发送消息——>服务端接受消息——>代表双方的连接已经建立;
    • request = sock.recv(1024) :表示接受数据的大小,可以是1024,2048,4096,都可以;
    • 将接收到的客户端socket对象保存到client变量中,将远程连接的详细信息保存到address变量中。然后,创建一个新的线程,让它指向handle_client函数,并传入client变量;

(是不是有点难理解,没关系,我也不是很懂这个,所以我才要讲后面的第二版代码

效果显示

我们分别执行服务端以及客户端的代码,得到如下结果:

在这里插入图片描述

服务端接收结果:

在这里插入图片描述

客户端结果:

在这里插入图片描述
在这里插入图片描述

不出意外,客户端发送一次信息后就自己结束了会话;

  • 注意:只有客户端发送数据,服务端接收到数据并返回数据后,才能算一次完整的会话(TCP三次握手)
  • 不然的话只能算是TCP半连接

代码实现(第二版—可以实时通信,并由客户端主动结束会话)

第二版代码优化地方:

  • TCP服务端不再使用handle_client这种难理解的函数操作;
  • 双方可以实现实时通信,并由客户端主动结束会话;

TCP客户端:

import socketip = '127.0.0.1'
port = 9990def Tcp_Client():# 还是老样子,像创建socket对象client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)client.connect((ip,port))print(f'已成功连接到服务端:{ip}:{port}')try:while(True):# 正常情况——发送信息到服务端,并将信息encodesend_msg = input("请输入客户端要发送的信息:")client.send(send_msg.encode('utf-8'))# 异常情况——若发送bye,等待服务端恢复后结束会话if send_msg.lower() == 'bye':data = client.recv(4096)# 解析data# data_decode = data.decode()# (这里我就不创建data_encode变量了,两者效果一样)print(f"已收到服务端的回复:{data.decode('utf-8')},即将结束对话")# 正常情况——接受服务端的数据data = client.recv(4096)if not data:# 如果服务端返回数据为空print("服务端已异常断开连接")break# 正常情况——双方还在正常通信# data_decode = data.decode('utf-8')print(f"收到服务端发来的信息:{data.decode('utf-8')}")finally:client.close()print("客户端已关闭")if __name__ == "__main__":Tcp_Client()

作用:客户端负责连接服务端、发送消息并接收回复,流程为:创建 socket → 连接服务端 → 收发数据 → 关闭连接。

改进之处

在这里插入图片描述

TCP服务端:

import socket# 0.0.0.0表示任何人都可访问TCP服务端
ip = "0.0.0.0"
port = 9990def Tcp_Server():server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 绑定IP和portserver.bind((ip,port))# 开始监听连接(最大等待连接数为5)server.listen(5)print(f"[*] Listening on {ip}:{port}")# 当连接建立的时候client,address = server.accept() # 好奇这两个变量的内容是什么# 所以打印出来看看print(f'Client including {client}')print(f'address including {address}')print(f'Accept data from {address}') # address的内容:{ip}:{port}try:while(True):# 接收客户端信息data = client.recv(4096)if not data:print("客户端已断开连接")break# 解析datadata_decode = data.decode()print(f"收到客户端信息:{data_decode}")# 如果客户端发送bye,则通信结束if data_decode.lower() == 'bye':send_msg = "Receive your message,looking forward to next time"client.send(send_msg.encode('utf-8'))break# 发送回复的消息send_msg_server = input("请输入回复给客户端的消息:")client.send(send_msg_server.encode('utf-8'))finally:client.close()server.close()print("服务端已关闭")if __name__ == "__main__":Tcp_Server()

作用:服务端负责监听连接、接收客户端消息并回复,流程为:创建 socket → 绑定地址 → 监听 → 接受连接 → 收发数据 → 关闭连接。


改进之处
可以看到处理数据的部分我们将其从hander_client函数变成了更加简洁易懂的代码:

在这里插入图片描述

效果显示:

客户端开启:

在这里插入图片描述

服务端监听:

在这里插入图片描述

客户端发送信息:Hello,I Love you

在这里插入图片描述

在这里插入图片描述

服务端回复:I konw

在这里插入图片描述

客户端发送:bye
(主动结束对话)

在这里插入图片描述
在这里插入图片描述

异常情况:

如果之前打开过代码,想要再次打开时,遇到错误:

Tcp_Server
server.bind((ip,port))
OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

这个错误的原因是:端口9990已被其他程序占用,导致当前服务端无法绑定到该端口(同一端口在同一时间只能被一个程序占用)。

解决方法(任选一种):
方法1:更换一个未被占用的端口

直接修改代码中的port变量,使用一个未被占用的端口(例如99919992等,确保端口号>1024):

# 将原来的port = 9990 改为其他端口,比如:
port = 9991  # 新端口

修改后重新运行服务端即可(客户端连接时也需要使用新端口)。

方法2:关闭占用9990端口的程序

如果必须使用9990端口,需要找到并关闭占用该端口的进程:

  1. 打开命令提示符(CMD)或PowerShell(以管理员身份运行);
  2. 输入命令查找占用9990端口的进程ID(PID):
    netstat -ano | findstr :9990
    
    输出类似:TCP 0.0.0.0:9990 0.0.0.0:0 LISTENING 1234,其中1234就是进程ID;
  3. 关闭该进程:
    • 方法1(命令行):输入 taskkill /PID 1234 /F1234替换为实际PID,/F表示强制关闭);
    • 方法2(图形化):打开「任务管理器」→ 「详细信息」→ 找到对应PID的进程,右键结束任务。

总结

我知道网络安全编程是有点无聊,但我个人觉得,正是这些无聊甚至烦躁理解代码的过程,才是你之后超越别人的重要优势;
所以,请坚持下去,期待下次再见!

http://www.dtcms.com/a/528953.html

相关文章:

  • 基于多尺度特征融合的自注意力度量学习的小样本故障诊断
  • UVa 1227 The Longest Constant Gene
  • datasophon1.2.1 二开
  • 建大网站首页华为商城网站建设
  • 运放的虚短和虚断
  • 建设网站公司兴田德润在哪里谷歌seo外链
  • 是“浴盆曲线”失灵,还是HDD变好了?
  • Tuesday JS,一款可视化小说编辑器
  • 景区旅游网站平台建设方案销售案例网站
  • 【小白笔记】input() 和 print() 这两个函数
  • 营销型网站哪家做的好东莞app
  • 部署PHP8.4(KylinV10SP3、Ubuntu2204、Rocky9.3)
  • 一套配置 双重体验:孪易 IOC 化解 端/流双渲染应用难题
  • jQuery Mobile 实例
  • 免费行情软件网站mnw做教育网站
  • WordPress网站hym地图凯里做网站
  • 东莞做网站优化哪家好网站识别手机电脑代码
  • Java---String类
  • Flame 中使用 GameWidget(完整使用手册)
  • html5制作手机网站做淘宝代码的网站
  • P2216 [HAOI2007] 理想的正方形
  • 设计模式23种-C++实现
  • 涌现的架构:集体智能框架构建解析
  • 大模型技术的核心之“效率高”
  • 分类网站怎么做seo什么网站出项目找人做
  • Unity 3D笔记(进阶部分)——《B站阿发你好》
  • 怎样建设好网站如何评判一个网站建设的怎么样
  • 【017】旅游网
  • 两款实用电脑工具:屏幕监控与文件整理,提升工作效率
  • 用php做的网站有写软文怎么接单子