Python实现socket库网络通信套接字

Socket 套接字:通讯端点 简介

socket起源于Unix,而Unix/Linux基本哲学之一就是“一切皆文件”,对于文件用【打开】【读写】【关闭】模式来操作。socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO、打开、关闭)。

Socket 是任何一种计算机网络通讯中最基础的内容。Socket通讯一般用户C/S结构系统的网络通讯。

Socket 网络通讯是基于TCP(传输控制协议)或UDP(用户数据报协议)两种协议通讯,所以有 面向连接(TCP )与无连接(UDP ) 两种通讯方式。

Python 要创建TCP 套接字就得在创建的时候,指定套接字类型为SOCK_STREAM,它使用 TCP/IP通讯协议。

Socket网络通信套接字

socket库提供了一个底层C API,可以使用BSD套接字接口实现网络通信。它包括socket类,用于处理具体的数据通道,还包括用来完成网络相关任务的函数,如将一个服务器名转换为一个地址以及格式化数据以便在网络上发送。

什么是套接字?

套接字是程序在本地或者通过互联网来回传递数据时所用通信通道的一个端点。

套接字有2个主要属性用于控制如何发送数据:地址簇(address family)控制所用的OSI网络层协议;套接字类型(socket type)控制传输层协议。(参考《计算机网络》7层协议)

地址簇

Python支持3个地址簇:

  • AF_INET:用于IPv4寻址。IPv4长度为4个字节,通常表示为4个数的序列,每个字节对应一个数,用点号分割(如121.63.0.243)。这些值通常被称为IP地址。目前IPv4依旧还是主流。
  • AF_INET6:用于IPv6寻址。目前IPv6已经小范围应用,它支持128位地址和通信流调整,还支持IPv4不支持的一些路由特性。
  • AF_UNIX:用于UNIX域套接字(UDS)的地址簇,这是一种POSIX兼容系统上的进程间通信协议。UDS的实现通常允许操作系统直接从进程向进程间传递数据,而不用通过网络栈。这比使用AF_INET更高效,但是由于要用到文件系统作为寻址的命令空间,所以UDS仅限于同一个系统上的进程。

套接字类型

套接字类型有两种:

  • SOCK_DGRAM:面向消息的数据报传输,数据报套接字通常与UDP关联,即用户数据报协议。这些套接字能提供不可靠的消息传送。
  • SOCK_STREAM:面向流的传输,与TCP相关,即传输控制协议。它们可以在客户和服务器之间提供字节流,通过超时管理,重传和其他特性确保提供消息传送或失败通知。

大多数应用协议(如HTTP)都建立在TCP基础上,因为这样更容易创建自动处理消息排序和传送的复杂应用。

UDP通常用于顺序不太重要的协议(如DNS交换)。UDP与TCP都支持IPv4与IPv6。

套接字的简单应用

gethostbyname_ex()与gethostbyname()

socket库包含一些与网络上的域名服务交互的函数,比如解析域名为IP地址可以用到gethostbyname_ex(),示例如下:

import socket

host_str = [
    'www.baidu.com',
    'cloud.tencent.com',
    'www.csdn.net'
]
for host in host_str:
    try:
        name, aliases, addresses = socket.gethostbyname_ex(host)
        print(host)
        print("主机名:", name)
        print("所有别名:", aliases)
        print("所有可用IP地址:", addresses)
    except socket.error as msg:
        print(host, msg)

运行之后,效果如下:

gethostbyname_ex:该函数返回3个参数,主机名,别名,以及解析能跳转到当前主机的IP地址。

gethostbyname:类似的函数,只返回当前主机的IP地址。

getservbyname()与getservbyport()

socket库提供getservbyname()函数用于查找网络服务的端口号和标准名,示例如下所示:

import socket
from urllib.parse import urlparse

url_str = [
    'https://www.baidu.com',
    'https://www.csdn.net',
    'smtp://smtp.qq.com',
]
for url in url_str:
    try:
        parsed_url = urlparse(url)
        port = socket.getservbyname(parsed_url.scheme)
        print(url)
        print("端口号:", port)
    except socket.error as msg:
        print(url, msg)

运行之后,效果如下:

当然,其实最有用的并不是给定一个链接去查询端口号,而是逆向操作。(因为标准化服务端口号一般都是固定的)

socket库提供getservbyport()函数用于完成逆向的服务端口查找,示例代码如下所示:

import socket

url = '{}://smtp.qq.com'.format(socket.getservbyport(25))
print(url)

运行之后,效果如下:

getprotobyname()

socket库还可以使用getprotobyname()函数获取分配给一个传输协议的端口号,示例如下:

import socket

#获取匹配开头字符串的所有属性值
def getConstants(prefix):
    return {
        getattr(socket, n): n
        for n in dir(socket)
        if n.startswith(prefix)
    }
ipproto_str = getConstants("IPPROTO_")
for agree in ['tcp', 'udp']:
    num = socket.getprotobyname(agree)
    name = ipproto_str[num]
    print(name, num)

运行之后,效果如下:

对于协议码,在程序定义中一般都是标准化常量,这就是意味着,它们的常量名都有一定的规律,而socket协议码前缀是IPPROTO_。

getaddrinfo(查找服务器地址)

getaddrinfo()函数用于将一个服务的基本地址转换为一个元组列表,其中包含建立一个连接所需要的全部信息。比如其网络簇与协议等,示例如下:

import socket

# 获取匹配开头字符串的所有属性值
def getConstants(prefix):
    return {
        getattr(socket, n): n
        for n in dir(socket)
        if n.startswith(prefix)
    }
ipproto_str = getConstants("IPPROTO_")
family_str = getConstants("AF_")
type_str = getConstants("SOCK_")
for response in socket.getaddrinfo('www.csdn.net', 'http', family=socket.AF_INET, type=socket.SOCK_STREAM,
                                   proto=socket.IPPROTO_TCP, flags=socket.AI_CANONNAME):
    family, socktype, ipproto, canonname, sockaddr = response
    print("地址簇:       ", family_str[family])
    print("套接字类型:    ", type_str[socktype])
    print("协议码:       ", ipproto_str[ipproto])
    print("主机规范名:    ", canonname)
    print("ip地址与端口号:", sockaddr)

运行之后,效果如下:

这里如果只用socket.getaddrinfo(‘www.csdn.net', ‘http'),表示不需要过滤任何连接信息,但大型的网站一般都有几个IP或者域名跳转到主页的。

所以通过后面的参数,可以筛选自己需要的链接信息。

其中,最后一个参数socket.AI_CANONNAME表示如果主机有别名,那么结果中会包含服务器的标准名。所有没有这个标志,标准名为空。

IP地址的表示方式

如果读者有C的经验,那么肯定知道,通过C语言编写的套接字程序是使用struct sockaddr结构体,它将IP地址表示为二进制,而不是上面显示的Python字符串形式。

如果想在Python和C之间转换IPv4地址,可以使用inet_aton()和inet_ntoa()。示例如下:

import socket
import binascii

ip_list = [
    "192.168.50.1",
    "127.0.0.1"
]
for ip in ip_list:
    packed = socket.inet_aton(ip)
    print("原始字符串ip地址:", ip)
    print("C库能识别的ip地址", binascii.hexlify(packed))
    print("还原C库ip地址字符串", socket.inet_ntoa(packed))
    print()

运行之后,效果如下:

inet_pton()与inet_ntop()

相信读者如果在测试上面代码,那么输入上面inet_aton()函数时,一定看到提醒中还有inet_pton()与inet_ntop()函数。

这2个函数既能处理IPv4也能处理IPv6,而inet_aton()和inet_ntoa()只能处理IPv4。它们的使用方式如下:

import socket
import binascii

ipv6_str = "2001:0db8:3c4d:0015:0000:0000:1a2f:1a2b"
packed = socket.inet_pton(socket.AF_INET6, ipv6_str)
print("原始字符串ip地址:", ipv6_str)
print("C库能识别的ip地址", binascii.hexlify(packed))
print("还原C库ip地址字符串", socket.inet_ntop(socket.AF_INET6, packed))
print()

ipv4_str = "192.168.50.1"
packed = socket.inet_pton(socket.AF_INET, ipv4_str)
print("原始字符串ip地址:", ipv4_str)
print("C库能识别的ip地址", binascii.hexlify(packed))
print("还原C库ip地址字符串", socket.inet_ntop(socket.AF_INET, packed))
print()

运行之后,效果如下:

以上就是Python实现socket库网络通信套接字的详细内容,更多关于Python socket库的资料请关注我们其它相关文章!

(0)

相关推荐

  • 用Python进行websocket接口测试

    我们在做接口测试时,除了常见的http接口,还有一种比较多见,就是socket接口,今天讲解下怎么用Python进行websocket接口测试. 现在大多数用的都是websocket,那我们就先来安装一下websocket的安装包. pip install websocket-client 安装完之后,我们就开始我们的websocket之旅了. 我们先来看个炒鸡简单的栗子: import websocket ws = websocket.WebSocket() ws.connect("ws://

  • python socket网络编程步骤详解(socket套接字使用)

    一.套接字套接字是为特定网络协议(例如TCP/IP,ICMP/IP,UDP/IP等)套件对上的网络应用程序提供者提供当前可移植标准的对象.它们允许程序接受并进行连接,如发送和接受数据.为了建立通信通道,网络通信的每个端点拥有一个套接字对象极为重要.套接字为BSD UNIX系统核心的一部分,而且他们也被许多其他类似UNIX的操作系统包括Linux所采纳.许多非BSD UNIX系统(如ms-dos,windows,os/2,mac os及大部分主机环境)都以库形式提供对套接字的支持.三种最流行的套接

  • 详解python3中socket套接字的编码问题解决

    一.TCP 1.tcp服务器创建 #创建服务器 from socket import * from time import ctime #导入ctime HOST = '' #任意主机 PORT = 21567 #随机提供个端口号 BUFSIZ = 1024 # 缓冲区大小设置为1KB,可以根据网络性能和程序需要改变这个容量 ADDR = (HOST, PORT) tcpSerSock = socket(AF_INET, SOCK_STREAM) #分配了 TCP 服务器套接字 tcpSerSo

  • Python中socket网络通信是干嘛的

    Socket是什么 Socket是一个抽象层,连接了应用层与传输层,是一组接口. 在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议. 所以,我们无需深入理解tcp/udp协议,socket已经为我们封装好了,我们只需要遵循socket的规定去编程,写出的程序自然就是遵循tcp/udp标准的.建立网络通信连接至少要一对端口号(socket).socket本质是编程接

  • Python实现socket库网络通信套接字

    Socket 套接字:通讯端点 简介 socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.socket就是该模式的一个实现,socket即是一种特殊的文件,一些socket函数就是对其进行的操作(读/写IO.打开.关闭). Socket 是任何一种计算机网络通讯中最基础的内容.Socket通讯一般用户C/S结构系统的网络通讯. Socket 网络通讯是基于TCP(传输控制协议)或UDP(用户数据报协议)两种协议

  • Python网络编程之TCP套接字简单用法示例

    本文实例讲述了Python网络编程之TCP套接字简单用法.分享给大家供大家参考,具体如下: 上学期学的计算机网络,因为之前还未学习python,而java则一知半解,C写起来又麻烦,所以一直都没有真正实现过TCP套接字编程. 最近学习了python,而用它来写套接字又十分方便简单,所以当然要试一试咯. 下面根据代码来介绍一下最简单的tcp程序,由客户端输入数据,发送给服务器,服务器加上时间后返回给客户端 #!/usr/bin/python 'test TCP server' from socke

  • python 基于TCP协议的套接字编程详解

    基于TCP协议的套接字编程 实现电话沟通为例,这里传递的是字符,可以自己尝试去发送一个文件 # 服务端 import socket # 1. 符合TCP协议的手机 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # TCP # 2. 绑定手机号 一个服务器,我们自己的电脑作为服务器的话,用自己的IP地址 server.bind(('127.0.0.1',8000)) # 127.0.0.1 代表本地 # server.bind(

  • Java套接字(Socket)网络编程入门

    网络应用模式主要有: 主机/终端模式:集中计算,集中管理: 客户机/服务器(Client/Server,简称C/S)模式:分布计算,分布管理: 浏览器/服务器模式:利用Internet跨平台. www(万维网)就是建立在客户机/服务器模式上,以HTML语言和HTTP协议为基础,能够提供各种Internet服务的信息浏览系统.网络信息放在主机的不同位置,www服务器利用超文本链路链接各项信息.www客户机(浏览器Brower)负责与服务器建立联系,向服务器发送请求,处理HTML超媒体,提供图形用户

  • python实现socket简单通信的示例代码

    首先先来简单介绍下socket: (具体更详细介绍的可以在网上找找,都讲得非常详细),这里主要是我自己的一些理解. socket是在应用层与传输层之间的一个抽象层,它的本质是编程接口,通过socket,才能实现TCP/IP协议. 它就是一个底层套件,用来处理最底层消息的接受和发送. socket翻译为套接字,可以把TCP/IP复杂的操作抽象为简单的几个接口来供应用层调用来实现进程在网络中的通信.socket起源于Unix,而Unix的基本要素之一就是"一切都为文件",即可以通过打开--

  • python利用socket实现客户端和服务端之间进行通信

    目录 一.socket socket通信的条件:IP和端口 形象比喻 二.客户端实现过程 三.服务器实现过程 四.演示 五.实现持续通信过程 前言: 今天教大家通过Python进行Socket网络编程(做一个聊天程序),可以实现在不同的主机(电脑)之间进行通话. 具体效果如何,接着往下看: 可以看到客户端(上方)向服务器端(下方)发送了内容,服务器端进行了回复 [备注:客户端是我的本机,服务器是另一条主机(阿里云服务器)] 两台主机的目的:验证两台主机可以相互通信 一.socket 先简单给大家

  • Linux进程间通信——使用流套接字

    前面说到的进程间的通信,所通信的进程都是在同一台计算机上的,而使用socket进行通信的进程可以是同一台计算机的进程,也是可以是通过网络连接起来的不同计算机上的进程.通常我们使用socket进行网络编程,这里将会简单地讲述如何使用socket进行简单的网络编程. 一.什么是socket socket,即套接字是一种通信机制,凭借这种机制,客户/服务器(即要进行通信的进程)系统的开发工作既可以在本地单机上进行,也可以跨网络进行.也就是说它可以让不在同一台计算机但通过网络连接计算机上的进程进行通信.

  • python基础之Socket套接字详解

    前言 Python语言提供了Socket套接字来实现网络通信. Python的应用程序通常通过Socket"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯. 服务器和客户端的源代码 服务器端 #coding=utf-8 #创建TCP服务器 import socket import time from time import ctime HOST = '127.0.0.1' PORT = 8080 BUFSIZE=1024 sock = socket.s

  • C#基于Socket套接字的网络通信封装

    本文为大家分享了C#基于Socket套接字的网络通信封装代码,供大家参考,具体内容如下 摘要 之所以要进行Socket套接字通信库封装,主要是直接使用套接字进行网络通信编程相对复杂,特别对于初学者而言.实际上微软从.net 2.0开始已经提供了TCP.UDP通信高级封装类如下: TcpListener TcpClient UdpClient 微软从.net 4.0开始提供基于Task任务的异步通信接口.而直接使用socket封装库,很多socket本身的细节没办法自行控制,本文目就是提供一种so

随机推荐