python tcp多个客户端连接服务器

一、传输层**
该层为两台主机上的应用程序提供端到端的通信。传输层有两个传输协议:TCP(传输控制协议)和 UDP(用户数据报协议)。其中,TCP是一个可靠的面向连接的协议,udp是不可靠的或者说无连接的协议。

二、TCP的特点:
TCP是面向运输层的协议。使用TCP协议之前,必须先建立TCP连接,在传输完成后,必须释放已经建立的TCP连接。
每条TCP连接只能有两个端,每一条TCP连接只能是点对点的。
TCP提供可靠的交付的服务。通过TCP连接传输的数据,无差错、不丢失、不重复,并且按序到达。
TCP提供全双工通信。TCP通信允许通信双发的任何时候都能发送数据。
TCP面向字节流。

三、TCP的连接
每一条TCP连接都有两个端点,TCP连接的端点叫做套接字(socket)或 插口。
套接字(socket)=(IP地址:端口号)
每一条TCP连接唯一的被通信两端的端点(即两个套接字)所确定,即:TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}

代码端
服务端

import socket
import threading

client_flag=0  #定义一个标志位

def client1(socket_tcp_server):   #采用了多线程
    global client_flag  #声明该变量可以在该方法使用

    # accept等待客户端连接
    # 如果有新的客户来连接服务器,那么就产生一个新的套接字连接客户端服务
    # new_client_socket用来为这个客户端服务
    # socket_tcp_server就可以省下专门等待其他客户连接
    
    new_client_socket, client_addr = socket_tcp_server.accept()  #当服务器得到客户端请求连接时,client_flag=1
    client_flag=1
    print("客户端连接成功",client_addr)
    
    while True:  
        # 接收数据
        recv_date = new_client_socket.recv(1024)  # 当客户端断开连接时,recv_date的值为空

        if recv_date: #使服务器能一直收到信息,只有客户端断开时,才退出循环
            print("client"+str(client_addr[1]%10000%1000%100%10)+":接收到的数据为:", recv_date.decode("gbk"))
        else:
            break

        #发送数据      
        send_date = "收到"
        new_client_socket.send(send_date.encode("gbk"))
    new_client_socket.close()  #关闭这个套接字

    print("对方已经结束了会话,等待新的连接")

def main():
    global client_flag
    socket_tcp_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #定义一个监听套接字
    socket_addr=("",7777)
    socket_tcp_server.bind(socket_addr) #服务器绑定一个端口
    
    socket_tcp_server.listen(128) # listen使套接字转变为被动连接,即类似等待客户端连接,而不是主动虚招客户端
    print("等待一个新客户端连接....")

    client1_threading = threading.Thread(target=client1, args=(socket_tcp_server,))
    client1_threading.start()

    while True:
        if  client_flag:   #当client_flag为1时,即服务器得到客户端请求连接时,开始一个新的线程
            
            
            client1_threading = threading.Thread(target=client1,args=(socket_tcp_server,)) #新建一个线程 
            client1_threading.start()  #开启这个线程
            client_flag = 0    #标志为,目的使线程不会一直增多,只有当服务器得到客户端请求连接时,才开始一个新的线程

if __name__ =='__main__':
    main()
    

客户端

import socket
import threading


def send_date(socket_tcp_client):   #发送数据
    while  True:
        server_date = input()   
        # 3.发送信息
        if server_date == "exit":  #当输入exit时,断开于服务器的连接
            break
        else:
            socket_tcp_client.send(server_date.encode("gbk"))  #发数据,enconde为编码 gbk为编码方式

    socket_tcp_client.close()  #关闭套接字



def recv_date(socket_tcp_client):  #接收数据
    
    while True:
    
        recv_date = socket_tcp_client.recv(1024)  #接收信息,每次最大为1024

        print("接收到的数据为:", recv_date.decode("gbk"))  #decode为解码,gbk为解码方式
        print("请输入要发送的数据:",end=" ")
        

def main():

    socket_tcp_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)  #创建一个套接字
    server_ip=input("请输入服务器的IP:")
    server_port=int(input("请输入服务器的port:"))
    print("请输入要发送的数据,输入exit退出会话:",end=" ")
    
    server_addr=(server_ip,server_port)
    socket_tcp_client.connect(server_addr)# 2.绑定连接

    send_tcp_date=threading.Thread(target=send_date,args=(socket_tcp_client,))  #定义两个线程,分别为发送和接收
    recv_tcp_date=threading.Thread(target=recv_date,args=(socket_tcp_client,))
    send_tcp_date.start()
    recv_tcp_date.start()   #开启这两个线程


if __name__ =='__main__':
    main()

测试:可以用pycharm运行一个服务器,再运行多个客户端测试,也可以把服务器代码放入虚拟机中。也可以用网络调试助手测试。

 

参考地址:https://blog.csdn.net/weixin_44636409/article/details/115797806

posted @ 2022-10-31 19:21  创客未来  阅读(1064)  评论(0编辑  收藏  举报