详解socket阻塞与非阻塞,同步与异步、I/O模型

yizhihongxing

一、socket阻塞与非阻塞

  1. 阻塞式socket

阻塞式socket在默认情况下处于阻塞状态,即程序会一直等待,直到数据准备好或者等待超时才返回结果。这种方式容易造成资源浪费,同时影响程序的性能。下面是一个阻塞式socket的示例:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.baidu.com", 80))
data = s.recv(1024)
print(data)
s.close()

上面代码会一直等待,直到服务器响应数据,并将响应的数据打印出来。

  1. 非阻塞式socket

非阻塞式socket在默认情况下处于非阻塞状态,即程序不会一直等待,而是立即返回结果。如果没有数据准备好,则会返回异常,需要通过轮询等方式来等待数据的准备。下面是一个非阻塞式socket的示例:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
try:
    s.connect(("www.baidu.com", 80))
except Exception as e:
    print(e)

data = None
while not data:
    try:
        data = s.recv(1024)
    except Exception as e:
        pass

print(data)
s.close()

上面代码将socket设置为非阻塞模式,所以connect调用可能会引发异常。当数据准备好后,通过while循环一直尝试读取数据,直到成功读取,然后将读取到的数据打印出来。

二、同步与异步

  1. 同步方式

在同步方式中,程序会一直等待,直到操作完成。这时程序不能继续执行其他任务,即是阻塞的。同步方式适用于处理简单的任务,但对于复杂的任务或者数据量较大的任务,会造成程序的阻塞,影响程序的性能。下面是一个同步方式的示例:

import requests

response = requests.get("http://www.baidu.com")
print(response.text)

上面代码会一直等待服务器响应,响应完后将响应内容打印出来。

  1. 异步方式

在异步方式中,程序可以同时处理多个任务或者数据,不需要一直等待,处理完成后回调通知程序结果。异步方式适用于复杂的任务或处理大量数据时,可以提高程序的性能。下面是一个异步方式的示例:

import asyncio
import aiohttp

async def main():
    async with aiohttp.ClientSession() as session:
        async with session.get("http://www.baidu.com") as response:
            print(await response.text())

asyncio.run(main())

上面代码使用asyncio和aiohttp库实现异步方式的请求,可以同时处理多个请求,提高了程序的性能。

三、I/O模型

  1. 阻塞I/O模型

在阻塞I/O模型中,程序会一直等待,直到数据准备好或等待超时才继续执行。这种方式在处理数据时容易造成资源的浪费和程序性能的下降。下面是一个阻塞I/O模型的示例:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("www.baidu.com", 80))
s.send(b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n")
data = s.recv(1024)
print(data)
s.close()

上面代码会一直等待服务器响应数据,如果响应数据较慢或者网络出现问题,程序就会一直处于等待状态。

  1. 非阻塞I/O模型

在非阻塞I/O模型中,程序会立即返回,处理完本次任务后可以继续执行其他任务。如果数据没有准备好,则会返回一个异常,需要通过轮询等方式等待数据准备就绪。下面是一个非阻塞I/O模型的示例:

import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setblocking(False)
try:
    s.connect(("www.baidu.com", 80))
except Exception as e:
    print(e)

s.send(b"GET / HTTP/1.1\r\nHost: www.baidu.com\r\nConnection: close\r\n\r\n")

data = None
while not data:
    try:
        data = s.recv(1024)
    except Exception as e:
        pass

print(data)
s.close()

上面代码将socket设置为非阻塞模式,并在数据发送后使用while循环轮询等待数据的准备。如果数据没有准备好,则会进行下一次轮询。

总的来说,socket阻塞与非阻塞、同步与异步、I/O模型是网络编程中比较重要的内容,掌握这些知识点对于编写高效的网络程序是十分有必要的。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解socket阻塞与非阻塞,同步与异步、I/O模型 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 详解前端自动化工具gulp自动添加版本号

    下面我将为你详细讲解如何使用gulp自动添加版本号来优化前端开发流程。 什么是gulp Gulp是一款基于Node.js的前端自动化构建工具,可以帮助开发者通过编写简单的任务脚本来自动化构建和打包前端代码。 为什么需要自动添加版本号 在前端开发中,经常需要通过添加版本号来强制刷新浏览器缓存,以确保更新后的代码能够立即生效。手动添加版本号费时费力,容易出错,因…

    node js 2023年6月8日
    00
  • node.js中的buffer.Buffer.isEncoding方法使用说明

    来介绍一下Node.js中的Buffer.isEncoding()方法。 方法介绍 Buffer.isEncoding(encoding)方法用来判断字符串编码是否为Node.js支持的合法编码名。如果传入的encoding参数不是字符串编码名,该方法返回false。该方法的原型定义如下: Buffer.isEncoding(encoding: string…

    node js 2023年6月8日
    00
  • node.js中的fs.fsyncSync方法使用说明

    下面是详细讲解“node.js中的fs.fsyncSync方法使用说明”的攻略: 什么是fs.fsyncSync方法? fs.fsyncSync方法是node.js的File System模块中一种同步的文件同步方法,它将缓存区中的数据写入被打开的文件中,并强制将任何挂起的文件系统操作写入磁盘。 如何使用fs.fsyncSync方法? 使用fs.fsyncS…

    node js 2023年6月8日
    00
  • Express框架之connect-flash详解

    当我们使用Express框架来构建Web应用时,我们会遇到一些需要在不同的HTTP响应间共享数据的情况,如用户登录后提示登录成功信息,或者在接收到用户提交表单后提示表单信息的验证结果等。为了解决这个问题,我们可以使用一个名为connect-flash的中间件。 本文将详细讲解如何使用connect-flash中间件来实现提示信息的传递和显示,并基于示例代码对…

    node js 2023年6月8日
    00
  • Node.js搭建WEB服务器的示例代码

    我会逐步为您讲解如何使用Node.js搭建WEB服务器,并提供两个示例说明。 什么是Node.js Node.js是基于Chrome V8 JavaScript引擎的开源的、跨平台的、事件驱动的JavaScript运行时环境。它使得开发者可以使用JavaScript编写后端服务器、命令行工具等应用程序。也就是说,使用Node.js可以将 JavaScript…

    node js 2023年6月8日
    00
  • nodejs中用npm初始化来创建package.json的实例讲解

    要创建一个Node.js项目,在开始编写代码之前,需要设置package.json文件,其中包含有用于项目的元数据(元信息)。 npm是Node.js的包管理器,它可以用来初始化一个空的package.json文件。下面是使用npm初始化创建package.json文件的实例讲解。 步骤 1:安装 Node.js 在进行任何操作之前,必须安装 Node.js…

    node js 2023年6月8日
    00
  • nodejs 中模拟实现 emmiter 自定义事件

    下面是详细讲解 “nodejs 中模拟实现 emitter 自定义事件” 的完整攻略。 1. 什么是 emitter 自定义事件 在 nodejs 中,EventEmitter 是一个非常重要的模块。其作用是提供了处理事件的基本机制,可以用于实现自定义事件。 实际上,EventEmitter 可以理解为用于注册和监听事件的中介。我们可以通过它来注册自定义事件…

    node js 2023年6月8日
    00
  • Node.js创建HTTP文件服务器的使用示例

    下面我将为您详细讲解如何使用Node.js创建HTTP文件服务器。 概述 Node.js是一个非常流行的JavaScript后端运行环境,它可以帮助我们轻松创建一个HTTP服务器并用于提供Web请求服务。本文将会介绍如何使用Node.js快速创建一个HTTP文件服务器。 步骤 步骤1:安装Node.js 首先我们需要安装Node.js,在官方网站 https…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部