一、多次通信
1.服务端
import socket
# 创建了一个基于ipv4,tcp协议的socket对象
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0',6666))
server.listen()
# 接收客户端的连接,创建socket连接对象,并且返回客户端的连接地址信息
# 阻塞
sock,addr = server.accept()
while True:
# 接收客户端发送的数据,1024指每次接收数据的大小
data = sock.recv(1024)
# 通过sock传入的是bytes类型的数据,需要解码才能正确显示
if data.decode == '886':
break
print(data.decode())
re_data = input()
sock.send(re_data.encode())
server.close()
sock.close()
2.客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',6666))
while True:
to_data = input()
client.send(to_data.encode())
data = client.recv(1024)
print(data.decode())
3.运行结果
二、多客户端连接(多线程/多进程)
1.服务端
import socket,threading
# 创建了一个基于ipv4,tcp协议的socket对象
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('0.0.0.0',6666))
server.listen()
# 接收客户端的连接,创建socket连接对象,并且返回客户端的连接地址信息
def handle_socket(sock,addr):
while True:
# 接收客户端发送的数据,1024指每次接收数据的大小
data = sock.recv(1024)
# 通过sock传入的是bytes类型的数据,需要解码才能正确显示
print('客户端' + str(addr[1]) + '发来消息:' + data.decode())
re_data = input()
sock.send(re_data.encode())
while True:
sock, addr = server.accept()
client_thread = threading.Thread(target=handle_socket,args=(sock,addr))
client_thread.start()
# server.close()
# sock.close()
2.客户端
import socket
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',6666))
while True:
to_data = input()
client.send(to_data.encode())
data = client.recv(1024)
print(data.decode())
3.运行结果
三、python原生的socket编程存在哪些问题?
- 在整个通信过程中,有很多不同的事件,不同的状态,这些事件需要我们处理,如果没有处理则极容易产生异常。
- 必须使用多线程/进程方式处理多个socket客户端的连接,而多线程在高并发场景下极容易发生C10K问题。(C10K是指单机连接数过万)
四、解决方案
I/O多路复用(使用一个线程,通过记录IO流的状态来同时管理多个IO流,当其中一个IO流的状态发生改变,比如客户端发送了消息过来变成可读状态,则再来通知该线程过来处理,通过这种方式可以大大提高服务器的吞吐能力,这种方式特别适合像socket网络编程这种IO密集型应用)