server.py
import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 第一个参数为套接字的地址家族AF_INET代表网络套接字,第二个参数SOCK_STREAM代表数据流式tcp协议 phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # 当服务端关闭时,再重启服务端,有时地址还没有释放,会出现Address already in use,可以通过设置SO_REUSEADDR重新使用地址,来避免此错误 phone.bind(('127.0.0.1', 8080)) # 监听当前服务器的ip地址与端口号 phone.listen(5) # 最大可以挂起5个连接 (backlog池中最大可有5个连接),后面的连接就无法连接 while True: # 循环接受客户端的连接,保证同时可以和多个客户端通信 conn, addr = phone.accept() # 得到一个tcp连接,等待客户端通过tcp三次握手 print( conn) # <socket.socket fd=196, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080), raddr=('127.0.0.1', 49851)> print(addr) # ('127.0.0.1', 49851) # conn 保存的是双向链接 ,addr保存的是客户端的ip地址及端口号 while True: # 循环进行发送和接收信息 try: msg = conn.recv(1024) # 等待客户端发消息 if not msg: break # mac系统在客户端强制断开时,不会捕捉异常,要使用此方法 print('客户端发来的消息是:', msg.decode('utf-8')) conn.send(msg.upper()) # 将客户端发来的信息大写后向客户端发送 except Exception: # 这里捕捉客户端强制退出的异常,如果客户端强制退出,则 break conn.close() # 通过tcp四次挥手关闭tcp连接 phone.close() # 关闭创建的socket对象
client.py
from socket import * phone = socket(AF_INET, SOCK_STREAM) # 第一个参数为套接字的地址家族AF_INET代表网络套接字,第二个参数SOCK_STREAM代表tcp协议 phone.connect(('127.0.0.1', 8080)) # 连接服务器的ip地址与端口号 while True: msg = input('===>').strip() if not msg: continue # 如果客户端发送的为空信息,那么消息不会发到服务端去,服务端无法从自己那一段的内核态中找到信息,就会卡住,因此要判断客户端输入的数据 phone.send(msg.encode('utf-8')) # 将客户端发送的信息转为二进制 data = phone.recv(1024) # 等待服务端发消息 print('收到服务端发来的消息', data.decode('utf-8')) phone.close() # 关闭客户端连接