tcp的服务器, 实现较为复杂
服务器实现流程
1.创建套接字
tcp_server_socket = socket.socket(socket.AF_INEF, socket.SOCK_STREAM)
2. 绑定信息
tcp_server_socket.bind("", 8888)
3.设置套接字为被动( 监听 )模式 ( 套接字默认是主动模式, 也就是客户端, 而服务器套接字必须设置此属性)
tcp_server_socket.listen(128)
4.等待客户端连接, (会进入阻塞状态)
此方法会返回一个元组, 分别是伪客户端socket (并不是接收了客户端socket, 而是一个专门为此客户端服务的socket客服, 保存了客户端socket的信息), 以及客户端地址
new_client_socket, client_addr = tcp_server_accept()
5.等待接收数据 ( 也会进入阻塞状态)
rec_data = new_client_socket.recv(1024)
6.关闭套接字
new_client_socket.close()
tcp_server_socket.close()
这里的new_client_socket, 可以理解为专门为此客户端服务的”客服”, 它既保存了客户端的一些信息, 又可以向客户端发送数据(使用send方法)
“客服”的身份, 是tcp和udp一大区别, 它可以向客户端回应消息, 而udp是做不到的, 比如在文件下载时, 不但有下行流量, 也有上行流量, 这是客户端和服务器在不断交互, 反复确认数据包是否送达而产生的流量
tcp服务器实例
循环为多个tcp客户端服务
import socket
def main():
# 1.创建套接字
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 2.绑定本地信息
tcp_server_socket.bind(("", 8889))
# 3.设置为被动模式
tcp_server_socket.listen(128)
# 循环为客户端服务
while True:
# 4. 等待客户端连接
new_client_socket, client_addr = tcp_server_socket.accept()
# 5.接收客户端数据
while True:
try:
recv_data = new_client_socket.recv(1024)
print(str(client_addr)+recv_data.decode("utf-8"))
# 回送一个消息给客户端
new_client_socket.send("recv--ok".encode("utf-8"))
except Exception as ex:
print("客户端终止连接, 等待下一个客户端")
break
tcp_server_socket.close()
if __name__ == "__main__":
main()
服务器正常情况下, 不应该终结客户端连接, 比如用户找人工客服, 用户可能有多个问题, 直接用户不再需要服务, 由用户终止连接
此外, 如果客户端终止了连接, 那么会在recv方法中获取到的不是数据, 而是null, 实际使用tcp服务器时应该判断此种情况