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

一、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日

相关文章

  • Nodejs初级阶段之express

    下面我将为您讲解Nodejs初级阶段之express的完整攻略,内容包括安装、配置、路由、中间件等。具体步骤如下: 安装 首先,安装 Node.js。安装完成后,执行以下命令安装 Express: npm install express –save 配置 在 js 文件中引入 Express 模块: const express = require(‘exp…

    node js 2023年6月8日
    00
  • nodejs批量修改文件编码格式

    下面详细讲解一下“nodejs批量修改文件编码格式”的完整攻略。 1. 背景介绍 在生产建设中,可能会有多个不同编码格式的文件。如果需要将他们全部改为同一种编码格式,可以使用Node.js批量修改这些文件的编码格式。 2. 环境准备 在开始之前,需要安装 Node.js 的最新版本,并安装 iconv-lite和 fs 模块。要安装,可以执行以下命令: np…

    node js 2023年6月8日
    00
  • JavaScript对象字面量和构造函数原理与用法详解

    JavaScript对象字面量和构造函数原理与用法详解 什么是JavaScript对象 在Javascript中,对象是指一组属性的集合,每个属性都是一个键值对。可以将它们看作是一些具有状态和行为的实体。JavaScript中有两种常见的对象创建方法:对象字面量和构造函数。在研究这两种方法之前,先来看看一般的对象创建方式: var person = {}; …

    node js 2023年6月8日
    00
  • 教你如何用node连接redis的示例代码

    下面是“教你如何用node连接redis的示例代码”的完整攻略: 一、什么是Redis? Redis是一个基于内存的数据结构存储系统,可以用作数据库、缓存和消息队列等。它支持多种数据结构,如字符串(常用于缓存)、哈希表、列表、集合和有序集合。Redis还提供了事务、持久化和读写分离等高级特性,是当今十分流行的数据存储方案之一。 二、Node.js操作Redi…

    node js 2023年6月8日
    00
  • nodejs代码执行绕过的一些技巧汇总

    标题:Node.js代码执行绕过的一些技巧汇总 一、概述 Node.js是一款非常流行的JavaScript运行环境,但在代码执行过程中可能也会出现漏洞使得攻击者可以执行一些不受欢迎的代码。本文将探讨几种绕过代码执行漏洞的技巧。 二、技巧汇总 绕过输入过滤 当从前端获取用户输入时,很重要的一步就是对数据进行输入检查。但只是检查数据的类型是不够的,因为攻击者可…

    node js 2023年6月8日
    00
  • node.js突破nginx防盗链机制,下载图片案例分析 原创

    首先,让我们先了解一下防盗链机制。当我们在网站上嵌入图片时,如果图片链接被其他网站使用,就会产生带宽消耗和服务器压力,并且影响到网站速度和稳定性。为了防止这种情况发生,网站会针对使用外链引用(盗链)的请求进行拦截,这就是防盗链机制。 但有时我们也需要让其他网站可以使用我们的图片,这时就需要通过一些方法绕过防盗链机制,这就是本文讲解的内容。 第一种方法:使用n…

    node js 2023年6月8日
    00
  • Node.js assert断言原理与用法分析

    Node.js Assert断言原理与用法分析 什么是断言? 断言是一种在运行时检测程序是否有误的方法。在编写测试程序时,测试程序会在特定条件下断言程序行为是否合乎预期。如果行为不如预期,则断言会抛出异常来指示错误。断言一般用于测试程序的健壮性以及程序的正确性。 Node.js assert模块 在Node.js中,可以使用内置的assert模块来实现断言。…

    node js 2023年6月8日
    00
  • 详解如何优雅在webpack项目实现mock服务器

    如何在Webpack项目中实现Mock服务器可以分为以下几个步骤: 第一步:安装相关依赖 在项目中需要安装以下依赖:webpack-dev-server、express和cross-env(如果是在Windows系统,需要用cross-env来设置环境变量)。使用npm可以通过以下命令安装: npm install webpack-dev-server ex…

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