zoukankan      html  css  js  c++  java
  • Python网络通信编程总结

    • 实现双向通信
    import socket
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('0.0.0.0',8002))
    server.listen()
    print('server 已经启动,欢迎连接')
    sock,addr = server.accept()
    while True:          #使用循环实现服务器端永久等待消息
        data=socl.recv(1024)
        print(data.decode())
        if data.decode()=='exit':       #如果客户端发来exit,就断开连接,判断语句要放在接收到客户端消息后,立刻执行,否则,不起作用。
            break    
        send_to_client=input()        #输入发送给客户端的消息
        sock.send(send_to_client.encode())
    server.close()                           #关闭客户端连接
    sock.close()                              #关闭sock连接
    #上述代码为服务器端代码
    #以下代码是客户端代码
    import socket
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8002))
    while True:
        send_to_server = input()
        client.send(send_to_server.encode())
        data = client.recv(1024)
        print(data.decode())
        if data.decode()=='exit':
            break
    client.close()

    以上代码只能实现一个客户端和服务器通信。要实现多个客户端和服务器通信,就需要使用线程。把每个客户端和服务器的连接都当做是一个线程,这样,线程之间互不干扰,顺利运行。

    import socket
    import threading
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('0.0.0.0',8002))
    server.listen()
    print('server 已经启动,欢迎连接')
    def handle_client(sock):           #定义函数,线程执行体
        while True:                #每一个线程和服务器的通信都是多次
        data = sock.recv(1024)
        print(data.decode())
        send_to_client = input()
        sock.send(send_to_client.encode())
    while True:              #服务器不知道客户端连接的数量,所以依然使用循环    
        sock,addr=server.accept()       #服务器连接到了一个客户端
        threading.Thread(target=handle_client,args=(sock,)).start()  #启动一个线程执行和客户端的交互

    在使用线程实现了多个客户端和服务器之间的通信后。

    要实现群聊的功能,就把服务器当做一个转发机构,专门转发各种客户端发来的信息。

    由于在客户端中input方法输入发送数据,而该方法是一个阻塞方法,必须先输入再发送。所以也可把客户端的接收,发送看做是一种线程,发送接收互不干扰。

    在群聊中,设置客户端标识,方便所有客户端明确信息从哪里发出。

    关闭某个客户端后,服务器不会报错,需要异常处理机制。

    import socket
    import threading
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('0.0.0.0',8004))
    server.listen()
    print('server 已经启动,欢迎连接')
    client_sockets = []
    def handle_client(sock):     #服务器转发数据,定义客户端标识,处理客户端退出异常
        try:              #处理某个客户端退出的异常
            username=sock.recv(1024).decode()      #接收客户端标识
            for client in client_sockets:      #发送消息说明每个客户端加入群聊
                client.send(('欢迎【'+username+'】加入群聊').encode())
            while True:        #接收客户端标识后,开始接收客户端消息
                data=sock.recv(1024).decode()     #接收客户端标识
                if len(client_sockets)>0:      #客户端列表中国如果有客户,向每个客户端发送消息
                    for client in client_sockets:
                        client.send((username+'说:'+data).encode())
        except Exception as e:
            client_socket.remove(sock)           #出现客户端退出群聊,服务器出现异常,删掉该连接
            for client in clietn_sockets:   #向每个客户端发送某客户端退出群聊
                client.send((username+'已退出群聊').encode())  
    while True:      #循环出现多个客户端连接
        sock,addr= server.accept()
        client_sockets.append(sock)      
        sock.send('欢迎加入群聊,请输入您的昵称:'.encode())
        threading.Thread(target=handle_client,args=(sock,)).start()  #启动服务器连接客户端
    #上述是实现群聊的完全代码
    #以下是客户端代码
    import socket
    import threading
    client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    client.connect(('127.0.0.1',8004))
    def receive(client):
        while True:
            print(client.recv(1024).decode())
    def sendto(client):
        while True:
            send_to_other_client = input()
            client.send(send_to_other_client.encode())
    threading.Thread(target=receive,args=(client,)).start()
    threading.Thread(target=sendto,args=(client,)).start()

    在群聊的基础上,实现私聊。需要使用字典数据类型存储每个客户端的连接和输入的昵称名。

    客户端的代码不需要做出改变。

    import socket
    import threading
    server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    server.bind(('0.0.0.0',8004))
    server.listen()
    print('server 已经启动,欢迎连接')
    client_sockets = {}  #使用字典数据类型,存放连接和输入昵称之间的映射
    def handle_client(sock):      #处理私聊
        try:    #处理私聊,某客户端退出群聊异常不能缺失
            username=sock.recv(1024).decode()    #获取输入昵称
            client_sockets[sock]=username   #连接和输入昵称相互匹配
            for client in client_sockets.keys():
                client.send(('欢迎【'+username+'】加入群聊').encode())
            while True:     #客户端输入循环
                data=sock.recv(1024).decode()   #服务器接受了客户端昵称后,再接受信息
                send_data = ''+username+'】说:'+data
                if data.startswith('@'):           #处理私聊,私聊以@开头
                    msg=data.split(' ')             #分割输入信息,
                    private_name=msg[0][1:]      #获取输入昵称
                    for k,v in client_sockets.items():  #遍历映射,查找符合的昵称
                        if v==private_name:      #找到符合的用户昵称
                            k.send(send_data.encode())   #向该昵称的连接发生私聊信息
                else:     #不是私聊,就是普通群聊
                    if len(client_sockets)>0:
                        for client in client_sockets.keys():  #依次遍历各个连接
                            client.send(send_data.encode())
        exception Exception as e:
            client_sockets.pop(sock)     #出现异常,删除连接
            for client in client_sockets.keys():
                client.send((username+'已退出群聊').encode())
    while True:         #客户端连接未知
        sock,addr=server.accept()
        client_sockets[sock]=''
        sock.send('欢迎您加入群聊,请输入您的昵称:'.encode())
        threading.Thread(target=handle_client,args=(sock,)).start()   #启动服务器,连接客户端
  • 相关阅读:
    毕业设计第一周第一天
    python添加水印
    python 连接MySQL数据库
    利用Python爬取免费代理IP
    Python将大的csv文件拆分多个小的csv文件
    Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/fs/FSDataInputStream
    org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: hdfs://localhost:9000/usr/local/spark/zytdemo
    Error: Could not open client transport with JDBC Uri: jdbc:hive2://localhost:10000: java.net.ConnectException: 拒绝连接 (Connection refused) (state=08S01,code=0)
    大数据常用命令
    硬件工程师必会电路模块之MOS管应用(转)
  • 原文地址:https://www.cnblogs.com/feng1014/p/12655373.html
Copyright © 2011-2022 走看看