阻塞和非阻塞网络、异步和非异步网络区别点

  在网络编程中,我们经常听到阻塞(Blocking)和非阻塞(Non-Blocking)、异步(Asynchronous)和非异步(Synchronous)这些概念。那么这些概念到底是什么意思呢?下面就让我来为大家简单介绍一下。

阻塞与非阻塞

  阻塞网络指的是当一个进程向另一个进程发送请求时,如果对方没有响应,那么当前进程会一直等待,直到对方返回结果或者超时。这种方式可以保证数据的可靠性,但是会导致程序的响应速度变慢,因为程序可能会因为等待而被阻塞住。
  相反,非阻塞网络是指当一个进程向另一个进程发送请求时,即使对方没有响应,当前进程也可以继续执行其他任务,不必等待对方的响应。这种方式可以提高程序的响应速度,但是会导致数据的可靠性降低,因为有可能因为没有等待到对方的响应而导致数据传输错误。下面是一个使用阻塞socket编写的TCP客户端代码示例:

python
import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('localhost', 5000)
client_socket.connect(server_address)

#发送数据
message = 'Hello, World!'
client_socket.sendall(message.encode())

#接收数据
data = client_socket.recv(1024)
print('Received: {}'.format(data.decode()))

# 关闭连接
client_socket.close()

  上述代码中,当客户端调用 connect()方法时,如果服务器没有响应,客户端将会被阻塞住,直到服务器返回结果或者超时。如果服务器没有正确响应,客户端将会一直等待,直到服务器返回结果或者超时。接下来,让我们来看一下使用非阻塞socket编写的TCP客户端代码示例:

python
import socket

client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.setblocking(False)

server_address = ('localhost', 5000)
try:
    client_socket.connect(server_address)
except BlockingIOError:
    pass

# 发送数据
message = 'Hello, World!'
while True:
    try:
        client_socket.sendall(message.encode())
        break
    except OSError:
        pass

# 接收数据
data = b''
while True:
    try:
        chunk = client_socket.recv(1024)
        if not chunk:
            break
        data += chunk
    except BlockingIOError:
        pass

print('Received: {}'.format(data.decode()))

# 关闭连接
client_socket.close()

  在上述代码中,当客户端调用 connect() 方法时,如果服务器没有响应,客户端不会被阻塞住,而是立即返回。如果服务器没有正确响应,客户端会定期检查是否已经连接成功,直到连接成功或者超时。

异步与非异步

  异步网络指的是当一个进程向另一个进程发送请求时,当前进程可以继续执行其他任务,而不必等待对方的响应。但是当对方响应时,当前进程需要进行回调操作,处理对方返回的结果。这种方式可以提高程序的响应速度,同时也可以保证数据的可靠性。
  相反,非异步网络是指当一个进程向另一个进程发送请求时,当前进程必须等待对方的响应,并且只有在接收到对方的响应后才能继续执行其他任务。这种方式虽然可以保证数据的可靠性,但是会导致程序的响应速度变慢。下面是一个使用异步socket编写的TCP客户端代码示例:

python
import socket

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

#设置为非阻塞模式
client_socket.setblocking(False)
server_address = ('localhost', 5000)

#连接服务器
try:
    client_socket.connect(server_address)
except BlockingIOError:
    pass

#发送数据
message = 'Hello, World!'
data_to_send = message.encode()
sent = 0
while sent < len(data_to_send):
    try:
        # 发送数据
        sent += client_socket.send(data_to_send[sent:])
    except BlockingIOError:
        pass

#接收数据
def handle_response(key, mask):
    global client_socket
    data = b''
    while True:
        try:
            chunk = client_socket.recv(1024)
            if not chunk:
                break
            data += chunk
        except BlockingIOError:
            break
    
    print('Received: {}'.format(data.decode()))
    client_socket.close()

#注册回调函数
import selectors
selector = selectors.DefaultSelector()
selector.register(client_socket, selectors.EVENT_READ, handle_response)

#开始事件循环
while True:
    events = selector.select()
    for key, mask in events:
        callback = key.data
        callback(key, mask)

  在上述代码中,我们首先将客户端socket设置为非阻塞模式,然后使用 connect() 方法连接服务器。接下来,我们发送数据并通过注册回调函数的方式接收数据。当有数据到达时,回调函数将会被自动调用。

总结

  阻塞和非阻塞主要区别在于是否等待对方响应,而异步和非异步主要区别在于回调操作的方式。在实际的网络编程中,我们需要根据具体的需求选择合适的方式来进行开发,以满足程序的特定需求。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值