tcp严格区分客户端和服务器
tcp客户端
客户端要比服务器简单很多,流程少很多
示例代码
import socket
def main():
# 创建tcp的套接字
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_ip = input("请输入要链接服务器ip:")
server_port = int(input("请输入要链接服务器port:"))
server_addr = (server_ip, server_port)
# 链接服务器
tcp_socket.connect(server_addr)
send_data = input("请输入要发送的数据:")
# 发送数据
tcp_socket.send(send_data.encode('gbk'))
# 关闭套接字
tcp_socket.close()
if __name__ == "__main__":
main()
tcp服务器
- socket创建套接字
- bind绑定ip和port (客户端一般不绑定,服务器一般绑定)
- listen使套接字变为可以被动链接
- accept等待客户端的链接
- recv/send接收发送数据
以一个例子简化理解:
- 买个手机
- 插上手机卡
- 设计手机为正常接通状态(能够响铃)
- 等待别人拨打
代码示例
import socket
def main():
# 创建tcp的套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定本地信息
tcp_server_socket.bind(('', 7890))
# 让默认的套接字由主动变为被动
tcp_server_socket.listen(128)
# 等待客户端链接 (**accept重点理解)
# accept返回值是一个元组(新的套接字,链接地址),直接进行拆包
# 监听套接字负责等待有新的客户端进行链接,
# accept产生新的套接字用来为客户端服务
# 默认阻塞,有客户端时解阻塞
print('---1---')
new_client_socket, client_addr = tcp_server_socket.accept()
print('---2---')
print(client_addr)
# 接收客户端发送的请求
recv_data = new_client_socket.recv(1024)
print(recv_data.decode('gbk'))
# 回送数据
new_client_socket.send("okok i know".encode('gbk'))
# 关闭套接字
new_client_socket.close()
tcp_server_socket.close()
if __name__ == "__main__":
main()
运行代码后会发现只输出了 —1—
因为此时是阻塞状态,等有客户端链接后才会解阻塞
当客户端连接后解阻塞
TCP循环服务
循环服务1.0
一个客户端只进行一次服务
import socket
def main():
# 创建tcp的套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定本地信息
tcp_server_socket.bind(('', 7890))
# 让默认的套接字由主动变为被动
tcp_server_socket.listen(128)
# 等待客户端链接 (**accept重点理解)
while True:
print("wait for new client")
new_client_socket, client_addr = tcp_server_socket.accept()
print("new client arrive %s" % str(client_addr))
# 接收客户端发送的请求
recv_data = new_client_socket.recv(1024)
print("client request:%s" % recv_data.decode('gbk'))
# 回送数据
new_client_socket.send("okok i know".encode('gbk'))
# 关闭套接字
new_client_socket.close()
print("server close and wait for new")
tcp_server_socket.close()
if __name__ == "__main__":
main()
运行结果
循环服务2.0
为多个客户端服务,且一个客户端可多次服务
import socket
def main():
# 创建tcp的套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定本地信息
tcp_server_socket.bind(('', 7890))
# 让默认的套接字由主动变为被动
tcp_server_socket.listen(128)
# 等待客户端链接 (**accept重点理解)
while True: # 循环为多个客户端服务
print("wait for new client")
new_client_socket, client_addr = tcp_server_socket.accept()
print("new client arrive %s" % str(client_addr))
while True: # 循环为一个客户端服务多次
# 接收客户端发送的请求
recv_data = new_client_socket.recv(1024)
print("client request:%s" % recv_data.decode('gbk'))
# 如果解阻塞,有两种可能
# 1. 客户端发送数据
# 2. 客户端关闭 此时recv_data为空
if recv_data:
# 回送数据
new_client_socket.send("okok i know".encode('gbk'))
else:
break
# 关闭套接字
new_client_socket.close()
print("server close and wait for new")
tcp_server_socket.close()
if __name__ == "__main__":
main()
两个服务器发送多次请求