Python Socket编程详解

背景

关于Python Socket编程,首先需要了解几个计算机网络的知识,通过以下的几个问题,有助于更好的理解Socket编程的意义,以及整个框架方面的知识:

TCP和UDP协议本质上的区别?

TCP协议,面向连接,可靠,基于字节流的传输层通信协议;UDP协议无连接,不可靠,基于数据包的传输层协议。

TCP协议在建立连接的过程需要经历三次握手,断开连接则需要经历四次挥手,而这建立连接的过程增加了传输过程中的安全性。
而建立连接的过程则会消耗系统的资源,消耗更多的时间,而相比较UDP协议传输过程则不会出现这种问题。

总结来讲,基于TCP协议传输,需要不断的确认对方是否收到信息,从而建立连接(确认过程次数有限制,即三次握手),UDP协议传输则
不需要确认接收端是否收到信息,只需要将信息发给对方。

TCP/IP协议栈、HTTP协议、Socket之间的区别和联系?

TCP/IP协议栈就是一系列网络协议,可以分为四层模型来分析:应用层、传输层、网络层、链路层;

HTTP协议(超文本传输协议)就是在这一协议栈中的应用层协议;HTTP协议简单来说,它的作用就是规范数据的格式,让程序能够方便的识别,并且收发双方都需要遵循同样的协议格式进行数据传输。(应用层的协议也和HTTP协议的作用类似,不一样的是定义不同的数据格式。)

Socket可以理解为TCP/IP协议栈提供的对外的操作接口,即应用层通过网络协议进行通信的接口。Socket可以使用不同的网络协议进行端对端的通信;

TCP Socket服务器的通信过程?

Server端:

建立连接(socket()函数创建socket描述符、bind()函数绑定特定的监听地址(ip+port)、listen()函数监听socket、accept()阻塞等待客户端连接)

数据交互(read()函数阻塞等待客户端发送数据、write()函数发送给客户端数据)

Client端:

建立连接(socket()函数创建socket描述符、connect()函数向指定的监听地址发送连接请求)

数据交互(wirte()函数发送服务端数据、read()函数足阻塞等待接受服务端发送的数据)

socket和websocket之间的联系?

webosocket是一种通信协议,不同于HTTP请求,客户端请求服务端资源,服务端响应的通信过程;websocket允许服务端主动
向客户端推送消息,同时做到客户端和服务端双向通讯的协议。(具体底层原理有待后面实践,暂时未接触)

HTTP,WSGI协议的联系和区别?

HTTP协议(超文本传输协议),属于TCP/IP协议栈中应用层的协议。用于规范传输数据的格式,是一种客户端和服务端传输的规则。

WSGI协议则是Python定义的Web服务器和框架程序通信的接口规则。两者联系不大,强行说的话,Python框架程序主要处理的是HTTP请求。

(后期可以实现一个WSGI协议的Python框架,用于处理HTTP请求的实验。)

主流Web框架,异步Web框架?

主流Web框架:Django、Flask

异步Web框架:Tornado(内置异步模块)、Snaic(Python自带asyncio)、FastAPI(基于Starlette库) 、aiohttp(基于asyncio)

asyncio,aiohttp之间的联系?(异步编程)

asyncio是一个异步IO库,aiohttp就是基于asyncio的异步HTTP框架(支持客户端/服务端)

代码设计

Python提供了基本的socket模块:

  1. socket模块;提供了标准的BSD Sockets API;
  2. socketserver模块:提供了服务器中心类,简化服务器的开发;

TCP Socket服务端

socket模块:

# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM

def echo_handler(sock ,address):
	print("Get Connection from address:", address)

	while True:
		response = sock.recv(8192)
		if not response:
			break
		print(f"Got {response}")
		sock.sendall(response)

def echo_server(address, back_log=5):
	sock = socket(AF_INET, SOCK_STREAM)
	sock.bind(address)
	sock.listen(back_log)

	while True:
		sock_client, address = sock.accept()
		echo_handler(sock_client, address)

if __name__ == "__main__":
	echo_server(('localhost', 5000))

代码详解:

  • 创建一个基于IPV4和TCP协议的Socket,这里AF_INET指的是使用IPV4协议,SOCK_STREAM指定使用面向流的TCP协议,绑定监听端口,设置等待连接的最大数量
  • 创建一个永久循环,获取客户端请求的连接,accept()会等待并返回一个客户端的连接;
  • 连接建立后,等待客户端数据,接受完客户端数据,然后返回数据给客户端,最后关闭连接

存在的问题:当出现多个客户端请求时,由于是单个线程会发生阻塞的情况,所以如果需要多线程处理多个客户端请求,可以这样改;

from threading import Thread

while True:
        client_sock, address = sock.accept()
        thread = Thread(target=echo_handler, args=(client_sock, address))
        thread.start()

这样的话,就会在每个客户端请求的时候,生成一个子线程然后处理请求;
(但是存在一个问题:当突然大量请求连接,消耗系统资源达到上限后,很可能造成程序无法处理后续请求。)

socketserver模块:

from socketserver import BaseRequestHandler, TCPServer

class EchoHandler(BaseRequestHandler):
    def handle(self):
        print("Got Connection From: %s" % str(self.client_address))
        while True:
            msg = self.request.recv(8192)
            if not msg:
                break
            self.request.send(msg)

if __name__ == "__main__":
    server = TCPServer(("", 5000), EchoHandler)
    server.serve_forever()
from socketserver import StreamRequestHandler, TCPServer, ThreadingTCPServer
import time

class EchoHandler(StreamRequestHandler):
    def handle(self):
        print("Got Connection Address: %s" % str(self.client_address))
        for line in self.rfile:
            print(line)
            self.wfile.write(bytes("hello {}".format(line.decode('utf-8')).encode('utf-8')))

if __name__ == "__main__":
    serv = ThreadingTCPServer(("", 5000), EchoHandler)
    serv.serve_forever()

代码详解:

  • 处理多个客户端,初始化一个ThreadingTCPServer实例;
  • 设置绑定的IP地址和端口,以及处理类;
  • 使用StreamRequestHandler(使用流的请求处理程序类,类似file-like对象,提供标准文件接口简化通信过程),重写里面的handle方法,获取请求数据,返回数据给客户端;

TCP Socket客户端

socket模块:

# -*- coding: utf-8 -*-
from socket import socket, AF_INET, SOCK_STREAM
import time

def request_handler():
	start_time = time.time()
	sock_client = socket(AF_INET, SOCK_STREAM)
	sock_client.connect(('localhost', 5000))

	book_content = ""
	with open("send_books.txt", "r") as f:
		book_content = f.read()

	content_list = book_content.split("\n")
	for content in content_list:
		if content:
			sock_client.send((content).encode())
			time.sleep(2)
			response = sock_client.recv(8192)
			print(response)

	end_time = time.time()
	print("总共耗时:", end_time-start_time)

if __name__ == "__main__":
	request_handler()

UDP Socket

Socket模块:

from socket import socket, AF_INET, SOCK_DGRAM
import time

def time_server(address):
    sock = socket(AF_INET, SOCK_DGRAM)
    sock.bind(address)

    while True:
        msg, addr = sock.recvfrom(8192)
        print('Get message from', addr)
        resp = time.ctime()
        sock.sendto(resp.encode('ascii'), addr)

if __name__ == "__main__":
    time_server(('', 5000))

代码不详解,和之前的差不多,注意不同的协议就完事了

客户端测试:

from socket import socket, AF_INET, SOCK_DGRAM

if __name__ == "__main__":
    s = socket(AF_INET, SOCK_DGRAM)
    s.sendto(b'hello', ('localhost', 5000))
    text = s.recvfrom(8192)
    print(text)

socketserver模块:

from socketserver import BaseRequestHandler, UDPServer
import time

class TimeHandler(BaseRequestHandler):
    def handle(self):
        print("Got Connection %s".format(str(self.client_address)))
        data = self.request[0]
        print(data)
        msg, sock = self.request
        print(msg)
        data = time.ctime()
        sock.sendto(data.encode('ascii'), self.client_address)

if __name__ == "__main__":
    u = UDPServer(("localhost", 9999), TimeHandler)
    u.serve_forever()

代码不在赘述,如果需要多线程处理并发操作可以使用ThreadingUDPServer

总结

关于本篇介绍Python Socket编程,大都是皮毛,只是谈到了Python实际处理socket的几个模块,
关于socket底层方面的知识并未提及,先了解个大概,从实际使用方面出发,在实际使用过程中结合
计算机网络知识,能够对socket在整个TCP/IP协议栈中的作用。

socket和socketserver模块都可以用来编写网络程序,不同的是socketserver省事很多,你可以专注
业务逻辑,不用去理会socket的各种细节,包括不限于多线程/多进程,接收数据,发送数据,通信过程。

以上就是Python Socket编程详解的详细内容,更多关于Python Socket编程的资料请关注我们其它相关文章!

(0)

相关推荐

  • 基于python3的socket聊天编程

    本文实例为大家分享了基于python3的socket聊天编程,供大家参考,具体内容如下 阶段一:最简易的聊天系统 缺点:程序不够完善,只能一来一回,且没人每次只能说一句话 server端: import socket HostPort = ('127.0.0.1',9999) s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.bind(HostPort) s.listen(1) conn,addr = s.accept() #print

  • python粘包问题及socket套接字编程详解

    粘包问题 TCP协议在传输过程中会出现数据粘包问题 讲一下TCP和UDP的区别,都是传数据的协议,没有好坏之说,只是不同的应用需求可能会更好选择哪一个协议 TCP:适合传输数量大 ,需要建立连接,会出现粘包问题,粘包问题可以解决,确定传入的长度,接收同样长度就可以保证一次性传输完 UDP: 适合传输数据量小,没有粘包,不需要连接,一次性传输,下一次就是新的数据,弊端就是数据丢失,不安全 QQ是用什么协议呢?按理应该可以用UDP协议,但是实际用的是TCP协议,这是历史遗留问题,可还记得我们输入QQ

  • python Socket网络编程实现C/S模式和P2P

    C/S模式 由于网络课需要实现Socket网络编程,所以简单实现了一下,C/S模式分别用TCP/IP协议与UDP协议实现,下面将分别讲解. TCP/IP协议 TCP/IP协议是面向连接的,即客户端与服务器需要先建立连接后才能传输数据,以下是服务器端的代码实现. 服务端: import socket from threading import Thread def deal(sock,addr): print('Accept new connection from {}:{}'.format(ad

  • python网络编程:socketserver的基本使用方法实例分析

    本文实例讲述了python网络编程:socketserver的基本使用方法.分享给大家供大家参考,具体如下: 本文内容: socketserver的介绍 socketserver的使用 socketserver的异步服务端 首发时间:2018-03-21 也可以使用socketserver来创建socket socketserver的介绍: socketserver是标准库中的一个高级模块 socketserver可以简化创建客户端跟创建服务端的代码 socketserver的使用: 首先导入模

  • python网络编程socket实现服务端、客户端操作详解

    本文实例讲述了python网络编程socket实现服务端.客户端操作.分享给大家供大家参考,具体如下: 本文内容: socket介绍 TCP: 服务端 客户端 UDP: 服务端 客户端 首发时间:2018-02-08 01:14 修改: 2018-03-20 :重置了布局,增加了UDP 什么是socket: socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求. 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为

  • Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】

    本文实例讲述了Python 网络编程之UDP发送接收数据功能.分享给大家供大家参考,具体如下: demo.py(UDP发送数据): import socket # 导入socket模块 def main(): # 创建一个udp套接字 udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # 绑定本机ip和端口号 (发送数据时,如果不绑定,系统会随机分配端口号.接收数据时,一般需要手动绑定ip和端口) udp_socket.b

  • Python 网络编程之TCP客户端/服务端功能示例【基于socket套接字】

    本文实例讲述了Python 网络编程之TCP客户端/服务端功能.分享给大家供大家参考,具体如下: demo.py(TCP客户端): import socket def main(): # 1. 创建tcp的套接字 tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 2. 链接服务器 # tcp_socket.connect(("192.168.33.11", 7890)) server_ip = input(

  • python SOCKET编程基础入门

    一.UDP编程 1.客户端Client:发起访问的一方. 2.服务器端 3.server段编程 (1)建立socket,socket是负责具体通信的一个实例 (2)绑定,为创建的socket指派固定的端口和IP地址 (3)接受对方发送内容 (4)给对方发送反馈,此步骤为非必须步骤 4.Client端编程 (1)建立通信的socket (2)发送内容到指定服务器 (3)接受服务器给定的反馈内容 5.模拟一下这个过程 (1)我们先建立一个服务器的函数 #服务器案例 import socket ​ #

  • python socket通信编程实现文件上传代码实例

    这篇文章主要介绍了python socket通信编程实现文件上传代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 写一个file_receive.py和一个file_send.py程序,由file_send.py上传一个文件,file_receive.py接收上传的文件,写到指定的包内 #file_receive.py import socket,subprocess,os BASE_DIR = os.path.dirname(os.pa

  • Python Socket编程详解

    背景 关于Python Socket编程,首先需要了解几个计算机网络的知识,通过以下的几个问题,有助于更好的理解Socket编程的意义,以及整个框架方面的知识: TCP和UDP协议本质上的区别? TCP协议,面向连接,可靠,基于字节流的传输层通信协议:UDP协议无连接,不可靠,基于数据包的传输层协议. TCP协议在建立连接的过程需要经历三次握手,断开连接则需要经历四次挥手,而这建立连接的过程增加了传输过程中的安全性. 而建立连接的过程则会消耗系统的资源,消耗更多的时间,而相比较UDP协议传输过程

  • Python基础教程之tcp socket编程详解及简单实例

    Python tcp socket编程详解 初学脚本语言Python,测试可用的tcp通讯程序: 服务器: #!/usr/bin/env python # -*- coding: utf-8 -*- import socket import threading import time def tcplink(sock, addr): print('Accept new connection from %s:%s...' % addr); sock.send(b'Welcome!!!'); whi

  • Python网络编程详解

    1.服务器就是一系列硬件或软件,为一个或多个客户端(服务的用户)提供所需的"服务".它存在唯一目的就是等待客户端的请求,并响应它们(提供服务),然后等待更多请求. 2.客户端/服务器架构既可以应用于计算机硬件,也可以应用于计算机软件. 3.在服务器响应客户端之前,首先会创建一个通信节点,它能够使服务器监听请求. 一.套接字:通信端点 1.套接字 套接字是计算机网络数据结构,它体现了上节中所描述的"通信端点"的概念.在任何类型的通信开始之前,网络应用程序必须创建套接字

  • python 网络编程详解及简单实例

    python 网络编程详解 网络编程的专利权应该属于Unix,各个平台(如windows.Linux等).各门语言(C.C++.Python.Java等)所实现的符合自身特性的语法都大同小异.在我看来,懂得了Unix的socket网络编程,其他的形式的网络编程方法也就知道了.这句话说得还不太严谨.准确的应该说成懂得了socket编程的原理,网络编程也就知道了,不同之处就在于每个平台,每个语言都有自己专享的语法,我们直接灵活套用就行了. 下面是用python实现的最基本的网络编程的例子,即依托于客

  • C#中的Socket编程详解

    目录 一,网络基础 二,Socket 对象 SocketType ProtocolType AddressFamily 三,Bind() 绑定与 Connect() 连接 Bind() Connect() 四,Listen() 监听请求连接 和 Accept() 接收连接请求 Listen() Accept() 五,Receive() 与 Send() Receive() 参数 返回 Send() 六,释放资源 close() 七,IPAddress 和IPEndPoint IPAddress

  • IOS开发网络篇—Socket编程详解

    一.网络各个协议:TCP/IP.SOCKET.HTTP等 网络七层由下往上分别为物理层.数据链路层.网络层.传输层.会话层.表示层和应用层. 其中物理层.数据链路层和网络层通常被称作媒体层,是网络工程师所研究的对象: 传输层.会话层.表示层和应用层则被称作主机层,是用户所面向和关心的内容. http协议对应于应用层 tcp协议对应于传输层 ip协议对应于网络层 三者本质上没有可比性.  何况HTTP协议是基于TCP连接的. TCP/IP是传输层协议,主要解决数据如何在网络中传输:而HTTP是应用

  • PHP SOCKET编程详解

    1. 预备知识 一直以来很少看到有多少人使用php的socket模块来做一些事情,大概大家都把它定位在脚本语言的范畴内吧,但是其实php的socket模块可以做很多事情,包括做ftplist,http post提交,smtp提交,组包并进行特殊报文的交互(如smpp协议),whois查询.这些都是比较常见的查询. 特别是php的socket扩展库可以做的事情简直不会比c差多少. php的socket连接函数 1.集成于内核的socket 这个系列的函数仅仅只能做主动连接无法实现端口监听相关的功能

  • php的socket编程详解

    php的socket编程算是比较难以理解的东西吧,不过,我们只要理解socket几个函数之间的关系,以及它们所扮演的角色,那么理解起来应该不是很难了,在笔者看来,socket编程,其实就是建立一个网络服务的客户端和服务端,这和mysql的客户端和服务端是一样的,你只要理解mysql的客户端和服务端是怎么一回事,你就应该能够理解下面我要讲的东西吧. 关于socket编程所涉及到的网络协议,什么TCP啊,UDP啊,什么socket三次握手等等,这些网络协议网上有很详细的解释,这里不讲,只截个sock

  • Java Socket编程详解及示例代码

    Socket,又称为套接字,Socket是计算机网络通信的基本的技术之一.如今大多数基于网络的软件,如浏览器,即时通讯工具甚至是P2P下载都是基于Socket实现的.本文会介绍一下基于TCP/IP的Socket编程,并且如何写一个客户端/服务器程序. 餐前甜点 Unix的输入输出(IO)系统遵循Open-Read-Write-Close这样的操作范本.当一个用户进程进行IO操作之前,它需要调用Open来指定并获取待操作文件或设备读取或写入的权限.一旦IO操作对象被打开,那么这个用户进程可以对这个

  • Python GUI编程详解

    目录 Python GUI编程 项目学习. 1.点名器 a.导航栏 b.主体 c.逻辑 总结 Python GUI编程 0.创建窗口 import tkinter as tk #创建一个窗口 root = tk.Tk() root.mainloop() # 第2步,给窗口的可视化起名字 root.title('My Window') # 设置窗口最小和最大 root.minsize(300,300) root.maxsize(500,500) 1.Label和Button的使用 #!/usr/b

随机推荐