Python Module_Socket_网络编程

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: 目录目录Socket套接字套接字的原理套接字的数据处理方式套接字类型Socket 标准函数ServerSocket 标准函数ClientSocket 标准函数公有标准函数Socket 编程编程思路DemoTCP 服务端TCP 客户端Socket套接字源 IP 地址和目的 IP 地址以及源端口号和目的端口号的组合称为套接字,是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,解决网络上两台主机之间的进程通信问题。

目录

Socket

套接字

源 IP 地址和目的 IP 地址以及源端口号和目的端口号的组合称为套接字,是支持 TCP/IP 的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,解决网络上两台主机之间的进程通信问题。简单的说就是通信双方的一种约定,用套接字中的相关函数来完成通信过程。其用于标识客户端请求的服务器和服务,是网络通信过程中端点的抽象表示,包含进行网络通信必需的五种信息:连接使用的协议、本地主机的IP地址、本地进程的协议端口、远地主机的 IP 地址、远地进程的协议端口(Socket = IP address + TCP/UDP + port)。应用层(HTTP)和传输层(TCP/UDP)就可以通过套接字接口,区分来自不同应用程序进程或网络连接的通信,实现数据传输的并发服务。

套接字的原理

Socket 可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序的桥梁,Socket 在应用程序中创建,通过绑定与网络驱动建立关系。此后,应用程序送给 Socket 的数据,由 Socket 交给网络驱动程序向网络上发送出去。计算机从网络上收到与该 Socket 绑定 IP 地址和端口号相关的数据后,由网络驱动程序交给 Socket,应用程序便可从该 Socket 中提取接收到的数据,网络应用程序就是这样通过 Socket 进行数据的发送与接收的。要通过 Internet 进行通信,至少需要一对套接字,其中一个运行在客户端,称之为 ClientSocket,另一个运行于服务器端面,称为 ServerSocket。根据连接启动的方式以及本地要连接的目标,套接字之间的连接过程可以分为三个步骤:

  • 服务器监听:是指服务端套接字并不定位具体的客户端套接字,而是处于等待连接的状态,实时监控网络状态。

  • 客户端请求:是由客户端的套接字提出连接请求,要连接的目标是服务器端套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器套接字的地址和端口号,然后再向服务器端套接字提出连接请求。

  • 连接确认:连接确认是当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,它就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的信息发送给客户端,一旦客户端确认了此连接,连接即可建立。而服务器端继续处于监听状态,继续接收其他客户端的连接请求。

套接字的数据处理方式

  • 同步模式:同步模式的特点是在通过 Socket 进行连接、接收、发送数据时,客户机和服务器在接收到对方响应前会处于阻塞状态,即一直等到收到对方请求才继续执行下面的语句。可见,同步模式只适用于数据处理不太多的场合。当程序执行的任务很多时,长时间的等待可能会让用户无法忍受,但同步模式的好处在于应用接口的访问有着更好的稳定性。

  • 异步模式:异步模式的特点是在通过 Socket 进行连接、接收、发送操作时,客户机或服务器不会处于阻塞方式,而是利用 callback 机制进行连接、接收、发送处理,这样就可以在调用发送或接收的方法后直接返回,并继续执行下面的程序。可见,异步套接字特别适用于进行大量数据处理的场合,使用 s.setblocking(0) 启用异步模式。

套接字类型

套接字类型 描述
socket.AF_UNIX 只能够用于单一的 Unix 系统进程间通信,同一台机器进程间通信
socket.AF_INET 服务器之间网络通信,Internet 进程间通信
socket.AF_INET6 IPv6
socket.SOCK_STREAM 流式 socket, for TCP,流套接字用于提供面向连接、可靠的数据传输服务。该服务将保证数据能够实现无差错、无重复发送,并按顺序接收。流套接字之所以能够实现可靠的数据服务,原因在于其使用了传输控制协议,即 TCP(The Transmission Control Protocol) 协议。
socket.SOCK_DGRAM 数据报式 socket, for UDP,数据报套接字提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用 UDP(User Datagram Protocol) 协议进行数据的传输。由于数据报套接字不能保证数据传输的可靠性,对于有可能出现的数据丢失情况,需要在程序中做相应的处理。
socket.SOCK_RAW 原始套接字,普通的套接字无法处理 ICMP、IGMP 等网络报文,而 SOCK_RAW 可以。其次,SOCK_RAW 也可以处理特殊的 IPv4 报文。此外,利用原始套接字,可以通过 IP_HDRINCL 套接字选项由用户构造 IP 头。原始套接字(SOCKET_RAW)允许对较低层次的协议直接访问,比如 IP、 ICMP 协议,它常用于检验新的协议实现,或者访问现有服务中配置的新设备,因为 RAW SOCKET 可以自如地控制 Windows 下的多种协议,能够对网络底层的传输机制进行控制,所以可以应用原始套接字来操纵网络层和传输层应用。比如,我们可以通过 RAW SOCKET 来接收发向本机的 ICMP、IGMP 协议包,或者接收 TCP/IP 栈不能够处理的IP包,也可以用来发送一些自定包头或自定协议的 IP 包。网络监听技术很大程度上依赖于 SOCKET_RAW
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)

UDP 和 TCP 的区别:
tcp是可靠的、面向连接的、尽力传输的协议,而udp是不可靠 的、面向非连接的、不尽力传输的协议。但是不可靠不代表它没有用,udp有自己的应用场景,语音和视频几乎都在使用udp协议,它的不可靠只是相对于 tcp来说的,但是它的好处就是效率,高效在某些场景要比可靠性重要。这就涉及trade-off了,也就是权衡,需要根据你的应用权衡利弊,然后进行选择。

NOTE:
1)TCP发送数据时,已建立好TCP连接,所以不需要指定地址。UDP是面向无连接的,每次发送要指定是发给谁。
2)服务端与客户端不能直接发送列表,元组,字典。需要字符串化 repr(data)。

Socket 标准函数

ServerSocket 标准函数

Socket 函数 描述
s.bind(address) 将套接字绑定到地址, 在AF_INET下,以元组(host,port)的形式表示地址.
s.listen(backlog) 开始监听TCP传入连接。backlog指定在拒绝连接之前,操作系统可以挂起的最大连接数量。该值至少为1,大部分应用程序设为5就可以了。backlog指定最多允许多少个客户连接到服务器。它的值至少为1。收到连接请求后,这些请求需要排队,如果队列满,就拒绝请求。
s.accept() 接受TCP连接并返回(conn,address),其中conn是新的套接字对象,可以用来接收和发送数据。address是连接客户端的地址。socket 进入“waiting”状态。客户请求连接时,方法建立连接并返回服务器。accept方法返回一个含有两个元素的元组(connection,address)。第一个元素connection是新的socket对象,服务器必须通过它与客户通信;第二个元素 address是客户的Internet地址。

ClientSocket 标准函数

Socket 函数 描述
s.connect(address) 连接到address处的套接字。一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex(adddress) 功能与connect(address)相同,但是成功返回0,失败返回errno的值。

公有标准函数

Socket 函数 描述
s.recv(bufsize[,flag]) 接受 TCP 套接字的数据。数据以字符串形式返回,bufsize 指定要接收的最大数据量。flag 提供有关消息的其他信息,通常可以忽略。recv 方法在接收数据时会进入「blocked」状态,如果发送的数据量超过了 recv 所允许的,数据会被截短。多余的数据将缓冲于接收端。以后调用 recv 时,多余的数据会从缓冲区删除(以及自上次调用 recv 以来,客户可能发送的其它任何数据)。
s.send(string[,flag]) 发送 TCP 数据。将 String 中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于 String 的字节大小。
s.sendall(string[,flag]) 完整发送 TCP 数据。将 String 中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回 None,失败则抛出异常。
s.recvfrom(bufsize[,flag]) 接受 UDP 套接字的数据。与 recv() 类似,但返回值是(data, address)。其中 data 是包含接收数据的字符串,address 是发送数据的套接字地址。
s.sendto(string[,flag],address) 发送 UDP 数据。将数据发送到套接字,address 是形式为 (ipaddr, port) 的元组,指定远程地址。返回值是发送的字节数。
s.close() 关闭套接字。
s.getpeername() 返回连接套接字的远程地址。返回值通常是元组(ipaddr, port)。
s.getsockname() 返回套接字自己的地址。通常是一个元组 (ipaddr, port)
s.setsockopt(level,optname,value) 设置给定套接字选项的值。
s.getsockopt(level,optname[,buflen]) 返回套接字选项的值。
s.settimeout(timeout) 设置套接字操作的超时期,timeout 是一个浮点数,单位是秒。值为 None 表示没有超时期。一般,超时期应该在刚创建套接字时设置,因为它们可能用于连接的操作(如: connect())
s.gettimeout() 返回当前超时期的值,单位是秒,如果没有设置超时期,则返回None。
s.fileno() 返回套接字的文件描述符。
s.setblocking(flag) 如果 flag 为 0,则将套接字设为非阻塞模式,否则将套接字设为阻塞模式(默认值)。非阻塞模式下,如果调用 recv() 没有发现任何数据,或 send() 调用无法立即发送数据,那么将引起 socket.error 异常。
s.makefile() 创建一个与该套接字相关连的文件

Socket 编程

编程思路

TCP 服务端:

  • 创建套接字,绑定套接字到本地 IP 与端口
  • 开始监听连接
  • 进入循环,不断接受客户端的连接请求
  • 然后接收传来的数据,并发送给对方数据
  • 传输完毕后,关闭套接字

TCP 客户端:

  • 创建套接字,连接远端地址
  • 连接后发送数据和接收数据
  • 传输完毕后,关闭套接字

这里写图片描述

Demo

TCP 服务端

Step 1:创建套接字,如果创建 socket 函数失败,会抛出一个 socket.error 的异常,需要捕获。

try:
    # create an AF_INET, STREAM socket (TCP)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    sys.exit()

Step 2:绑定 socket

HOST = ''   # Symbolic name meaning all available interfaces
PORT = 8888 # Arbitrary non-privileged port
ADDR = (HOST, RORT)
try:
    s.bind(ADDR)
except socket.error , msg:
    print 'Bind failed. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
    sys.exit()

Step 3: 监听连接

s.listen(5)

Step 4:接收请求

# wait to accept a connection - blocking call
conn, addr = s.accept()

Step 5:发送响应

# now keep talking with the client
data = conn.recv(1024)
conn.sendall(data)

Step 6:关闭 socket

s.close()

NOTE1:将上面的服务器程序改造成一直运行,最简单的办法是将 accept 放到一个循环中,那么就可以一直接收连接了。

# now keep talking with the client
while True:
    #wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    data = conn.recv(1024)
    reply = 'OK...' + data
    if not data: 
        break

    conn.sendall(reply)

conn.close()

NOTE2:多个 Client 可以随时建立连接,而且每个客户端可以跟服务器进行多次通信,将处理的程序与主程序的接收连接分开。一种方法可以使用线程来实现,主服务程序接收连接,创建一个线程来处理该连接的通信,然后服务器回到接收其他连接的逻辑上来。

这里写图片描述

  • 定义线程体函数
# Function for handling connections. This will be used to create threads
def client_thread(conn):
    # Sending message to connected client
    conn.send('Welcome to the server. Type something and hit enter\n') # send only takes string

    # infinite loop so that function do not terminate and thread do not end.
    while True:
        # Receiving from client
        data = conn.recv(1024)
        reply = 'OK...' + data
        if not data: 
            break

        conn.sendall(reply)

    # came out of loop
    conn.close()
  • 创建多线程
# now keep talking with the client
while True:
    # wait to accept a connection - blocking call
    conn, addr = s.accept()
    print 'Connected with ' + addr[0] + ':' + str(addr[1])

    # start new thread takes 1st argument as a function name to be run, second is the tuple of arguments to the function.
    start_new_thread(client_thread ,(conn,))

s.close()

TCP 客户端

Step 1:创建套接字,如果创建 socket 函数失败,会抛出一个 socket.error 的异常,需要捕获。

try:
    # create an AF_INET, STREAM socket (TCP)
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error, msg:
    print 'Failed to create socket. Error code: ' + str(msg[0]) + ' , Error message : ' + msg[1]
    sys.exit()

Step 2: 连接

remote_hostname = 'www.google.com'
try:
    # 获得远程主机的 IP 地址
    remote_ip = socket.gethostbyname(remote_hostname)
except socket.gaierror:
    #could not resolve
    print 'Hostname could not be resolved. Exiting'
    sys.exit()

s.connect((remote_ip , port))

Step 3:发送请求

try :
    #Set the whole string
    s.sendall(message)
except socket.error:
    #Send failed
    print 'Send failed'
    sys.exit()

Step 4:接收响应

reply = s.recv(4096)

Step 5:关闭 socket

s.close()
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
3天前
|
机器学习/深度学习 人工智能 算法
猫狗宠物识别系统Python+TensorFlow+人工智能+深度学习+卷积网络算法
宠物识别系统使用Python和TensorFlow搭建卷积神经网络,基于37种常见猫狗数据集训练高精度模型,并保存为h5格式。通过Django框架搭建Web平台,用户上传宠物图片即可识别其名称,提供便捷的宠物识别服务。
92 55
|
1月前
|
Python
Python中的异步编程:使用asyncio和aiohttp实现高效网络请求
【10月更文挑战第34天】在Python的世界里,异步编程是提高效率的利器。本文将带你了解如何使用asyncio和aiohttp库来编写高效的网络请求代码。我们将通过一个简单的示例来展示如何利用这些工具来并发地处理多个网络请求,从而提高程序的整体性能。准备好让你的Python代码飞起来吧!
71 2
|
1月前
|
数据采集 存储 JSON
Python网络爬虫:Scrapy框架的实战应用与技巧分享
【10月更文挑战第27天】本文介绍了Python网络爬虫Scrapy框架的实战应用与技巧。首先讲解了如何创建Scrapy项目、定义爬虫、处理JSON响应、设置User-Agent和代理,以及存储爬取的数据。通过具体示例,帮助读者掌握Scrapy的核心功能和使用方法,提升数据采集效率。
98 6
|
12天前
|
机器学习/深度学习 人工智能 算法
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
宠物识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了37种常见的猫狗宠物种类数据集【'阿比西尼亚猫(Abyssinian)', '孟加拉猫(Bengal)', '暹罗猫(Birman)', '孟买猫(Bombay)', '英国短毛猫(British Shorthair)', '埃及猫(Egyptian Mau)', '缅因猫(Maine Coon)', '波斯猫(Persian)', '布偶猫(Ragdoll)', '俄罗斯蓝猫(Russian Blue)', '暹罗猫(Siamese)', '斯芬克斯猫(Sphynx)', '美国斗牛犬
83 29
【宠物识别系统】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+图像识别
|
13天前
|
机器学习/深度学习 人工智能 算法
深度学习入门:用Python构建你的第一个神经网络
在人工智能的海洋中,深度学习是那艘能够带你远航的船。本文将作为你的航标,引导你搭建第一个神经网络模型,让你领略深度学习的魅力。通过简单直观的语言和实例,我们将一起探索隐藏在数据背后的模式,体验从零开始创造智能系统的快感。准备好了吗?让我们启航吧!
40 3
|
18天前
|
网络安全 Python
Python网络编程小示例:生成CIDR表示的IP地址范围
本文介绍了如何使用Python生成CIDR表示的IP地址范围,通过解析CIDR字符串,将其转换为二进制形式,应用子网掩码,最终生成该CIDR块内所有可用的IP地址列表。示例代码利用了Python的`ipaddress`模块,展示了从指定CIDR表达式中提取所有IP地址的过程。
35 6
|
21天前
|
机器学习/深度学习 自然语言处理 语音技术
Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧
本文介绍了Python在深度学习领域的应用,重点讲解了神经网络的基础概念、基本结构、训练过程及优化技巧,并通过TensorFlow和PyTorch等库展示了实现神经网络的具体示例,涵盖图像识别、语音识别等多个应用场景。
45 8
|
20天前
|
数据采集 XML 存储
构建高效的Python网络爬虫:从入门到实践
本文旨在通过深入浅出的方式,引导读者从零开始构建一个高效的Python网络爬虫。我们将探索爬虫的基本原理、核心组件以及如何利用Python的强大库进行数据抓取和处理。文章不仅提供理论指导,还结合实战案例,让读者能够快速掌握爬虫技术,并应用于实际项目中。无论你是编程新手还是有一定基础的开发者,都能在这篇文章中找到有价值的内容。
|
1月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
垃圾识别分类系统。本系统采用Python作为主要编程语言,通过收集了5种常见的垃圾数据集('塑料', '玻璃', '纸张', '纸板', '金属'),然后基于TensorFlow搭建卷积神经网络算法模型,通过对图像数据集进行多轮迭代训练,最后得到一个识别精度较高的模型文件。然后使用Django搭建Web网页端可视化操作界面,实现用户在网页端上传一张垃圾图片识别其名称。
77 0
基于Python深度学习的【垃圾识别系统】实现~TensorFlow+人工智能+算法网络
|
1月前
|
机器学习/深度学习 TensorFlow 算法框架/工具
利用Python和TensorFlow构建简单神经网络进行图像分类
利用Python和TensorFlow构建简单神经网络进行图像分类
56 3