一、什么是socket
socket就是一个抽象接口层,通过这些接口就可以调用底层协议实现数据包的接收和发送。
二、socket通信原理
socket通信和我们日常打电话的过程很像,下面是做了一个简单的比喻,用来更好的理解socket原理
socket 服务端:
1.首先你得有个电话 --> 生成socket对象
2.你的电话要有号码 --> 绑定本机ip+port
3.开始在家等电话 --> 开始监听电话listen
4.电话铃响了,接起电话,听到对方的声音 --> 接受新连接accept,conn.recv()
socket 客户端:
1.首先你得有个电话 --> 生产socket对象
2.输入你想拨打的电话 --> connect 远程主机ip+port
3.等待对方接听
4.say “hi kelly,今天晚上去打球嘛~” --> 通过socket send消息给服务端
5.等待回应——》响应回应——》等待回应。。。。
三、基于socket实现的聊天系统
3.1 功能介绍
该聊天系统主要实现客户端可以向服务端发送消息,服务端可以收到消息并回复客户端消息;当客户端关闭时,服务端可以捕获客户端断开连接的错误,服务端程序不会退出,可以继续等待下一个客户端建立连接。
3.2 代码实现
- server.py
import socket
# 服务端socket程序
ip = ''
port = 8888
# 1.创建服务端socket对象
socket_server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 2.绑定ip,port
socket_server.bind((ip, port))
# 3.开始监听
socket_server.listen(1) # 为1代表允许一个连接排队,更多的连接进来就会被拒绝
# 4.阻塞式的等待客户端连接
while True:
conn, addr = socket_server.accept() # 阻塞直到有新连接进来
with conn:
print("connect by", addr)
try:
while True:
data = conn.recv(1024)
print("server recevie peername and data:", conn.getpeername(), data.decode())
if data:
# conn.sendall(data) # 把收到的数据全部返回给客户端
response = input(">>>")
conn.sendall(response.encode())
print("send to client:", response)
else:
break
except ConnectionResetError as e:
print("远程连接断开")
- client.py
import socket
ip='localhost'
port=8888
socket_client=socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
socket_client.connect((ip,port))
while True:
msg=input(">>>")
if len(msg) == 0:
continue
socket_client.sendall(msg.encode())
# socket_client.sendall(b'hello world')
data=socket_client.recv(1024)
print('Received',data.decode())
3.3 运行结果
1.客户端没有断开情况下的消息发送和接收
server端:
client端:
2.客户端断开连接后的消息发送和接收
server端: (服务端程序不会退出,会重新和客户端建立起新的连接)
client端: