目录

Python中Socket编程 1

一、Socket概述 1

二、python中socket模块使用 1

三、socket之聊天室 3

四、socket之端口探测 7

五、scapy之tcp端口探测 11

Python中Socket编程

一、Socket概述

socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求。

socket即是一种特殊的文件,socket函数就是对其进行的操作(读/写IO、打开、关闭)

socket模块是针对 服务器端 和 客户端Socket 进行【打开】【读写】【关闭】

二、python中socket模块使用

通给指定地址簇和socket类型来进行创建

Socket地址簇 描述
socket.AF_UNIX 只能够用于单一的Unix系统进程间通信
socket.AF_INET 服务器之间网络通信IPv4
socket.AF_INET6 IPv6
socket类型 描述
socket.SOCK_STREAM 流式socket , for TCP
socket.SOCK_DGRAM 数据报式socket , for UDP
socket.SOCK_RAW 原始套接字,普通的套接字无法处理ICMP、IGMP等网络报文,而SOCK_RAW可以;其次,SOCK_RAW也可以处理特殊的IPv4报文;此外,利用原始套接字,可以通过IP_HDRINCL套接字选项由用户构造IP头。
socket.SOCK_SEQPACKET 可靠的连续数据包服务
创建TCP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
创建UDP Socket: s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
Socket常用函数 描述
sk.bind(address) 将socket绑定到地址。address地址的格式取决于地址族。在AF_INET下,以元组(host,port)的形式表示地址。
sk.listen(backlog) 开始监听传入连接。backlog指定在拒绝连接之前,可以挂起的最大连接数量。
sk.connect(address) 连接到address处的socket。一般,address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
sk.connect_ex(address) 同上,只不过会有返回值,连接成功时返回 0 ,连接失败时候返回编码,例如:10061
sk.close() 关闭socket
sk.recv(bufsize) 接受socket的数据。数据以字符串形式返回,bufsize指定最多可以接收的数量。
sk.send(string) 将string中的数据发送到连接的socket。
sk.sendall(string) 将string中的数据发送到连接的socket,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。
sk.settimeout(timeout) 设置socket操作的超时期,timeout是一个浮点数,单位是秒。超时期应该在刚创建socket时设置.
sk.accept() 接受连接并返回(conn,address),其中conn是新的socket对象,可以用来接收和发送数据。address是连接客户端的地址。

三、socket之聊天室

简单收发

编程思路

服务端:

1 创建socket,因为socket是特殊的文件(需要close),所以通过with
as来自动释放文件资源

with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as sk:

2 绑定套接字到本地IP与端口,开始监听连接

s.bind((HOST,PORT))
s.listen()

3接受客户端的连接请求,

conn, addr = s.accept()

4 通过accept创建的新socket对象接收数据并发送给对方数据

为了保证能收到所有发送来的信息,通过while循环来一直接受数据,直到数据为空

服务器端代码

import socketHOST = '127.0.0.1'
PORT = 33333with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:s.bind((HOST,PORT))s.listen()conn, addr = s.accept()with conn:print('conn by',addr)while True:data = conn.recv(1024)if not data:breakprint(data)conn.sendall(b'hello,client')

客户端代码

import socketHOST = '127.0.0.1'
PORT = 33333with socket.socket(socket.AF_INET,socket.SOCK_STREAM) as s:s.connect((HOST,PORT))s.sendall(b'hello,friend')data = s.recv(1024)print('rece',repr(data))

socket聊天室

服务器

问题1:首先服务器能同时连接多个客户端

Socket.listen()后通过while循环

sk.accept()不断接收新的连接并创建socket

问题2:服务器要连接客户端后能一直接受数据,直到接受到空数据

多个连接之间肯定是独立的,并行的

所以通过线程的方式来实现

问题3:服务器要指定客户端端口和地址后进行回复信息

通过while 循环来一直接收input数据来指定发送

但是上面为了处理多个客户端时,也用了while

所以将连接多个客户端写入函数通过线程来实现,使之并行

服务器代码

from socket import *
import threadingdef text_recv(CliSock,addr):while True:data = CliSock.recv(1024)print(addr,"send to you:",data)if not data:breakdef socket_up():SerSock = socket(AF_INET, SOCK_STREAM)SerSock.bind(('127.0.0.1',58787))SerSock.listen()while True:CliSock, addr = SerSock.accept()print('connnecting from:', addr)Host[str(addr[1])] = CliSockt = threading.Thread(target=text_recv,args=(CliSock,addr))t.start()if __name__ == '__main__':Host = {}t = threading.Thread(target=socket_up)t.start()while True:try:target_info = input('please input your target : msg,port >\n ').split(',')msg = target_info[0]port = target_info[1]conn = Host[port]conn.sendall(msg.encode())except Exception as e:print(e)

客户端

同服务端问题3一致

客户端代码

import threading
from socket import *def text_recv(SerSock):while True:data = SerSock.recv(1024)print("send to you:",data)if not data:breakif __name__ == '__main__':CliSock = socket(AF_INET, SOCK_STREAM)CliSock.connect(('127.0.0.1',58787))t = threading.Thread(target=text_recv, args=(CliSock,))t.start()while True:data1 = input('please input want send > \n')CliSock.send(data1.encode())if not data1:break

四、socket之端口探测

探测原理:当通过socket连接目标主机未开放端口时会传出异常

例:ConnectionRefusedError: [WinError 10061]
由于目标计算机积极拒绝,无法连接。

编程思路

1 通过线程创建socket,对目标主机的范围端口进行尝试连接

2.对于没有抛出异常的端口尝试接受数据了解端口信息

问题:有些端口开放但不能接收到信息,就会将进程卡在接受数据那

解决:通过给socket对象设置settimeout()属性来限制超时时间,当超过时间时抛出新的异常:即timeout

所以 except timeout 也是存活端口,但是端口信息没有获取到

3.将存活端口和端口信息加入到字典中,最后遍历输出

实现代码

import threading
from socket import *def port_find(p):try:with socket(AF_INET, SOCK_STREAM) as sk:sk.connect((HOST, p))sk.settimeout(3)alive[p] = sk.recv(1024).strip().decode()print("port[{}] is alive\n".format(p), end='')except timeout:print("port[{}] is alive\n".format(p), end='')alive[p] = 'this not have info'except:passif __name__ == '__main__':HOST = '10.30.25.199'alive = {}threads = []for p in range(1, 65535):t = threading.Thread(target=port_find, args=(p,))threads.append(t)t.start()for t1 in threads:t1.join()for k,v in alive.items():print(k,'--->',v)

connect_ex探究使用

connect_ex相对于connect来说多了返回值,连接成功时返回 0
,连接失败时候返回编码,例如:10061

那么就可以通过返回值来对是否存活进行判断

但是还是需要接收那些没有数据的端口,所以设置settimeout,然后在进一步尝试执行,成功就记录收到的数据,失败就表示端口开放但是没有数据

实现代码

import threading
from socket import *def port_find(p):with socket(AF_INET, SOCK_STREAM) as sk:re = sk.connect_ex((HOST, p))sk.settimeout(3)if re == 0:print("port[{}] is alive\n".format(p), end='')try:alive[p] = sk.recv(1024).strip().decode()except:alive[p] = 'this not have info'else:print("port[{}] is dead\n".format(p), end='')if __name__ == '__main__':HOST = '10.30.25.199'alive = {}threads = []for p in range(1, 65535):t = threading.Thread(target=port_find, args=(p,))threads.append(t)t.start()for t1 in threads:t1.join()for k,v in alive.items():print(k,'--->',v)

探究:因为线程开启太多会损害性能

那么如何用两个线程去完成socket的端口探测?

这里用到了python的队列(queue)

编程思想

将扫描的端口一次性put加入到队列中

调用二个子线程开始并行

回调函数中while不断利用get从队列取出端口号进行扫描

就实现了两个线程的并行扫描,互不干涉

实现代码

from socket import *
from queue import Queue
import threadingdef port_find():while not port_que.empty():p = port_que.get()with socket(AF_INET, SOCK_STREAM) as sk:re = sk.connect_ex((HOST, p))sk.settimeout(3)if re == 0:print("port[{}] is alive\n".format(p), end='')try:alive[p] = sk.recv(1024).strip().decode()except:alive[p] = 'this not have info'else:print("port[{}] is dead\n".format(p), end='')if __name__ == '__main__':HOST = '192.168.84.130'alive = {}threads = []port_que = Queue()for i in range(30):port_que.put(i)t1 = threading.Thread(target=port_find)t2 = threading.Thread(target=port_find)threads.append(t1)threads.append(t2)t1.start()t2.start()for t in threads:t.join()for k, v in alive.items():print(k, '--->', v)

五、scapy之tcp端口探测

抓包分析

失败流程:1.SYN-> 2.RST,ACK->

成功流程:1.SYN-> 2.SYN,ACK-> 3.ACK->

可知:Socket是通过tcp三次握手进行端口探测

scapy中TCP(flags=‘S’)可以实现第一次握手,发送SYN包

flags=‘SA’–SYN,ACK包,flags=’RA’—RST,ACK包

编程思路

先用scapy构造一个 flags 的值为 S 的报文,S 代表SYN,就是请求建立一个 TCP
连接,在接收到服务器返回的报文中,如果 flagw
上的值为SA(SYN,ACK),那么就代表服务器确定接收到发送的连接请求并同意建立连接,这时候客户端再回应一个AR(ACK,RST)报文,确定接收到服务器的响应,建立连接后又立刻断开。

实现代码

from scapy.all import *
from scapy.layers.inet import IP, TCPdef port_scan(port):packet = IP(dst=ip)/TCP(dport=port,flags='S')   # 构造一个 flags 的值为 S 的报文result = sr1(packet,timeout=2,verbose=0)if result.haslayer('TCP'):if result['TCP'].flags == 'SA':   # 判断目标主机是否返回 SYN+ACKsend = sr1(IP(dst=ip)/TCP(dport=port,flags='AR'),timeout=2,verbose=0) # 向目标主机发送 ACK+RSTprint('[+] {} is open'.format(port))elif result['TCP'].flags == 'RA':passif __name__ == '__main__':ip = '192.168.84.130'threads = []for p in range(1, 30):t = threading.Thread(target=port_scan, args=(p,))threads.append(t)t.start()for t in threads:t.join()

Python中Socket编程相关推荐

  1. python的socket编程_Python Socket编程详细介绍

    在使用Python做socket编程时,由于需要使用阻塞(默认)的方式来读取数据流,此时对于数据的结束每次都需要自己处理,太麻烦.并且网上也没找到太好的封装,所以就自己写了个简单的封装. 封装思路 1 ...

  2. python中socket怎么用_Python 之socket的应用

    本节主要讲解socket编程的有关知识点,顺便也会讲解一些其它的关联性知识: 一.概述(socket.socketserver): python对于socket编程,提供了两个模块,分别是socket ...

  3. Python中socket解读

    操作系统底层原理 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必须 ...

  4. Python学习,python中socket解读

    操作系统底层原理 操作系统:(Operating System,简称OS)是管理和控制计算机硬件与软件资源的计算机程序,是直接运行在"裸机"上的最基本的系统软件,任何其他软件都必须 ...

  5. Python:socket编程教程

    ocket是基于C/S架构的,也就是说进行socket网络编程,通常需要编写两个py文件,一个服务端,一个客户端. 首先,导入Python中的socket模块: import socket Pytho ...

  6. python中socket模块常用吗_python中socket模块详解

    socket模块简介 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket.socket通常被叫做"套接字",用于描述IP地址和端口,是一个通信 ...

  7. android c++ socket编程,C++ 中 socket编程实例详解

    C++ 中 socket编程实例详解 sockets(套接字)编程有三种,流式套接字(SOCK_STREAM),数据报套接字(SOCK_DGRAM),原始套接字(SOCK_RAW):基于TCP的soc ...

  8. python中IO编程中关于StringIO的读写问题

    阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量.文章设置为仅粉丝可见,是因为写博客确实花了不少精力.希望互相进步谢谢!! 文章目录 阅读前请看一下:我是一个热衷于记 ...

  9. Python基础-socket编程

    一.网络编程 自从互联网诞生以来,现在基本上所有的程序都是网络程序,很少有单机版的程序了. 计算机网络就是把各个计算机连接到一起,让网络中的计算机可以互相通信.网络编程就是如何在程序中实现两台计算机的 ...

最新文章

  1. 【Android 异步操作】Handler 机制 ( MessageQueue 空闲任务 IdleHandler 机制 )
  2. 随笔汇总_索取资料请进入
  3. 不停刷朋友圈的人_不停刷新闻、朋友圈、微信群的朋友,休息一下,看多了伤身!...
  4. Linux学习-15-学习LVM逻辑卷
  5. linkbot 中文教程系列 linkbot破解教程
  6. 在c 语言中 一个函数由函数头和,C语言程序设计基础教程_习题答案
  7. python 字符集转换-灰常慢
  8. Hadoop用户配置免密登陆
  9. 函数的参数个数是不固定_EXCEL这些序号技巧,你还真不一定都知道
  10. 2019牛客多校第二场E MAZE(线段树 + 矩阵)题解
  11. 程序包androidx.appcompat.app不存在
  12. 百度人脸识别:功能开通
  13. paip.提升用户体验-----c++ 实现360浏览器收藏动作星星动画效果
  14. devcon-计算机硬件设备的禁用与启动说明
  15. pe擦除服务器硬盘,怎么彻底删除硬盘数据
  16. 项目管理过程组-十五至尊图
  17. 微信小程序 - 小程序分享转发
  18. 支付宝支付成功之后的接口_继支付宝微信之后,51信用卡还款也开始收费了,手续费再创新高...
  19. C语言——用函数方法判断闰年
  20. com.alibaba.fastjson.JSONException: syntax error, pos 1

热门文章

  1. 网络舆情监测预警与联动应急机制
  2. 目前工业机器人可以替代哪些工种或者哪些从业人员的工作?
  3. 关于SQL server 内容乱码问题的资料收集
  4. solidity智能合约面试题
  5. DNGuard HVM 试用版 RC1 发布
  6. powershell 将文本转换成表格的还有一种方式
  7. 基于SpringBoot+微信小程序的农产品销售平台
  8. Oracle 的内存参数配置
  9. 把excel导入sqlserver外部表不是预期格式
  10. 开发技术-cant resolve localhost address java.net.UnknownHostException