IO模型——BIO

本文详细介绍了Socket通信的基本流程,包括客户端和服务器端的创建、连接、数据收发及关闭操作。同时,讲解了同步阻塞(BIO)模型在服务端的实现,分析了其在并发处理上的局限性,并提供了Python实现BIO的代码示例。通过这些内容,读者可以深入理解网络通信的基础和同步阻塞模型的工作原理。
摘要由CSDN通过智能技术生成

 一、socket通信流程

1.什么是套接字(scoket)

套接字(scoket): 对网络中不同主机上的应用进程之间进行双向通信的端点的抽象

socket=(IP地址:端口号)

2.socket通信流程

客户端程序开发:

  • 创建客户端套接字对象

socket.AF_INET IPV4   AF_INET6  ipv6  socket.SOCK_STREAM  TCP协议

tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

  • 和服务端套接字建立连接

tcp_client_socket.connect((host, port))

  • 发送数据  二进制数据

message = ‘hello’

message = message.encode(‘utf-8’)

tcp_client_socket.send(message)

  • 接收数据 最多接受1024个字节

tcp_client_socket.recv(1024)

  • 关闭客户端套接字

tcp_client_socket.close()

服务端程序开发:

  • 创建服务端端套接字对象

tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

当客户端和服务端建立连接后,服务端程序退出后端口号不会立即释放,需要等待大概1-2分钟。

  • 设置端口号复用

tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

  • 绑定端口号  host不写,不固定,

tcp_server_socket.bind((host,port))

  • 设置监听   backlog等待最大的连接数

tcp_server_socket.listen(backlog)

  • 等待接受客户端的连接请求  返回新的套接字

tcp_client, port = tcp_server_socket.accept()

  • 接收数据

tcp_client_socket.recv()

  • 发送数据

tcp_client_socket.send()

  • 关闭套接字

tcp_client.close()   进行通信

tcp_server_socket.close() 

tcp_server_socket不进行通信,服务端套接字,被动套接字,只用与等待接受客户端的连接请求

 二、同步阻塞(BIO)

  • 服务端采用单线程,当 accept 一个请求后,在 recv 或 send 调用阻塞时,将无法 accept 其他请求(必须等上一个请求处理 recv 或 send 完 )(无法处理并发)
  • 服务端采用多线程,当 accept 一个请求后,开启线程进行 recv,可以完成并发处理,但是,随着请求数增加需要增加系统线程,大量的线程占用很大的内存空间,并且线程切换会带来很大的开销,10000个线程真正发生读写实际的线程数不会超过20%,每次accept都开一个线程也是一种资源浪费。

python实现BIO的代码示例如下:

服务端:

import socket
import threading


def conn_client(server):
    while True:
        mesg = client.recv(1024)
        if len(mesg) == 0:
            break
        print(mesg.decode())
        send_msg = "hello111111111111"
        client.send(send_msg.encode())
    client.close()


if __name__ == '__main__':
    # 创建服务端套接字
    server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    # 设置端口复用
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 绑定端口号
    server.bind(('**.*.**.**', 8000))
    # 设置监听
    server.listen(1024)
    # 多客户端连接
    while True:
        client, port = server.accept()
        thread = threading.Thread(target=conn_client, args=(client,))
        thread.start()

    server.close()

客户端:

import socket

if __name__ == '__main__':
    client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
    client.connect(('**.*.**.**', 8000))
    # mes = "hello"
    while True:
        mes = input("发送的数据:")
        client.send(mes.encode())
        mes1 = client.recv(1024)
        print(mes1.decode())
    client.close()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值