本次实现用python模拟socket底层简单逻辑,。
一、服务端
import socket
# 主机地址未0,0,0,0,表示能绑定本机所有的网络接口ip地址
# 等待客户端来连接
IP = 'localhost'
PORT = 40000
BUFLEN = 1024
# 创建一个实例化的socket对象
# 参数AF_INET表示该socket网络层使用IP协议,设定好的枚举值
# 参数SOCK_STREAM表示该socket传输层使用tcp协议,设定好的枚举值
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 设定服务端的IP地址和端口
server_address = (IP, PORT)
# 将设定好的IP地址和端口输入实例化对象中,bind是这个类下的一个方法
listen_socket.bind(server_address)
# 调用类中的.listen方法,才能把这个服务置于监听状态
# 参数1表示,最多监听多少个监听口
listen_socket.listen(1)
print(f'{PORT} Waiting for client connection...')
# 收到客户端后,进入accept,接收到协议,并进行第二次握手(底层服务端实现)
client_socket, client_address = listen_socket.accept() # accept返回的是两个元组,用两个变量对应这个两个元素的元组。
# 上面产生了一个新的socket用来传输数据的socket(重要!),第二个获取了客户端的ip地址和端口号
print('Client connected:', client_address)
while True:
# 这个时候服务端就有两个socket了,一个是传输数据的socket,一个是监听的socket.
# 采用一个循环去无限接受客户端传过来的信息。
data = client_socket.recv(1024).decode('utf-8') # 用一个变量去接受传输数据socket中的recv方法传输的对象,并解码。注意返回的是一个字节窜!
# 根据他返回来什么类型的数据,进行什么样的处理,数据层的处理。
# 如果没有信息,就会停止在这里不动,直到客户端有信息发送过来
print('Received message:', data) # 然后就可以打印出来了。
# 如果data是空字节串,表示对方已经关闭了连接,就需要断开。
if not data:
break
massage = "login success"
client_socket.sendall(massage.encode('utf-8')) # 发送的数据必须是字节串类型,所以也要编码
# 利用cmd查看netstat -an|find/i "id"查看是否建立端口号,还会有另外2个端口出来传递消息。
client_socket.close() #一定要关闭端口,否则通道会一直在占用状态
listen_socket.close() #一定要关闭端口,否则监听会一直在占用状态
#二、客户端
# 与服务端一样,创建一个socket实例
import socket
# 服务端端口号
IP = 'localhost'
PORT = 40000
# 客户端端口号
client_IP = ('localhost', 8877)
# 与服务端是一样,创建一个实例化
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定客户端端口号
client_socket.bind(client_IP)
# 设定好IP地址和端口
client_address = (IP, PORT)
# 创建连接,通过类中的方法,还有形参,连接该地址,发起三次握手的第一次!对方accept后发起第三次握手!
client_socket.connect(client_address)
while True:
# 从用户终端输入字符串
data_send = input('输入要发送的消息:')
if data_send == 'exit':
break
# 发送的字符串要编码为字体串
client_socket.sendall(data_send.encode())
reved = client_socket.recv(1024)
print(reved.decode())
client_socket.close()