zoukankan      html  css  js  c++  java
  • 为了应对某人的需求,写了一个简单的聊天室内容

    Python聊天室

    背景

    这是一篇水文,同时也是更换markdown后的第一篇,主要是为了测试markdown的情况。

    服务器程序

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    """
    聊天室服务器程序v1.0.1
    作者:挖洞的土拨鼠
    联系:
        GitHub:https://github.com/cisp
        Blog:http://www.cnblogs.com/KevinGeorge/
    """
    
    #引入依赖包、库文件
    import sys
    import time
    import socket
    import select
    import logging
    import datetime
    
    
    #设置全局配置
    reload(sys)
    sys.setdefaultencoding("utf-8")
    logging.basicConfig(filename="./talkroom.log",level=logging.INFO,filemode='a',format='%(asctime)s-%(levelname)s:%(message)s')
    
    
    #定义全局变量
    test_port = 38080
    test_addr = "127.0.0.1"
    
    
    #定义全局函数
    def now():
        return str(datetime.datetime.now())
    
    
    #定义聊天室类
    class TalkRoom(object):
        """创建聊天室类"""
        def __init__(self,ipaddress,port,max):
            """
            构造函数:
                初始化聊天人字典结构
                初始化服务器套接字
                初始化轮询队列
            """
            self.__register_name_dictionary = {}
            self.__server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
            self.__server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            self.__server.bind((ipaddress,port))
            self.__server.listen(max)#设置聊天室最大限制人数
            self.__readable_socket_list = [self.__server]
            self.__writeable_socket_list = []
            self.__error_socket_list = [self.__server]
    
        def broadcast(self,sockfd,msg):
            for sock in self.__register_name_dictionary:
                if sock != sockfd:
                    try:
                        sock.send("
    "+msg)
                    except Exception,reason:
                        logging.info(reason)
                        sock.close()
                        self.broadcast(sock,"[%s %s]已经退出聊天室
    "%(self.__register_name_dictionary[sock][0],now()))
                        self.__register_name_dictionary.pop(sock)
    
        def running(self):
            while True:
                rs,ws,es = select.select(self.__readable_socket_list,self.__writeable_socket_list,self.__error_socket_list)
                for sockfd in rs:
                    if sockfd == self.__server:
                        client,addr = sockfd.accept()
                        self.__register_name_dictionary[client] = (None,addr)
                        client.send("请输入您的昵称:")
                        name = client.recv(1024)
                        self.__register_name_dictionary[client] = (name,addr)
                        self.broadcast(client,"[%s %s]刚刚进入聊天室
    "%(name,now()))
                        self.__readable_socket_list.append(client)
                        self.__error_socket_list.append(client)
                        continue
                    else:
                        try:
                            data = sockfd.recv(4096)
                            if data:
                                self.broadcast(sockfd,"[%s %s]"%(self.__register_name_dictionary[sockfd][0],now())+data)
                        except Exception,reason:
                            logging.info(reason)
                            sockfd.close()
                            self.broadcast(sockfd,"[%s %s]已经退出聊天室
    "%(self.__register_name_dictionary[sockfd][0],now()))
                            self.__register_name_dictionary.pop(sockfd)
                            self.__readable_socket_list.remove(sockfd)
                            self.__error_socket_list.remove(sockfd)
    
    
    if __name__ == "__main__":
        room = TalkRoom(test_addr,test_port,5)
        room.running()
    
    

    客户端程序

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    
    """
    聊天室客户端程序v1.0.1
    作者:挖洞的土拨鼠
    联系:
        GitHub:https://github.com/cisp
        Blog:http://www.cnblogs.com/KevinGeorge/
    """
    
    #引入依赖包、库文件
    import sys
    import time
    import select
    import socket
    import logging
    import datetime
    
    #设置全局配置
    reload(sys)
    sys.setdefaultencoding("utf-8")
    logging.basicConfig(filename="./talkclient.log",level=logging.INFO,filemode='a',format='%(asctime)s-%(levelname)s:%(message)s')
    
    
    #定义全局变量
    test_port = 38080
    test_addr = "127.0.0.1"
    
    
    #定义全局函数
    def now():
        return str(datetime.datetime.now())
    
    def inputflag() :
        sys.stdout.write('[MySelf %s]'%now())
        sys.stdout.flush()
    
    
    #定义客户端类
    class TalkClient(object):
        def __init__(self,ipaddress,port):
            self.__client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.__readable_socket_list = [sys.stdin,self.__client]
            self.__writeable_socket_list = []
            self.__error_socket_list = [self.__client]
            try:
                self.__client.connect(("127.0.0.1", 38080))
            except Exception,reason:
                logging.info(reason)
                exit(0)
            print "[MySelf %s]刚刚进入聊天室"%now()
            banner = self.__client.recv(1024)
            print banner
            name =raw_input()
            self.__client.send(name)
            inputflag()
    
        def running(self):
            while True:
                rs,ws,es = select.select(self.__readable_socket_list,self.__writeable_socket_list,self.__error_socket_list)
                for sockfd in rs:
                    if sockfd == self.__client:
                        data = self.__client.recv(4096)
                        if data:
                            sys.stdout.write(data)
                            inputflag()
                        else:
                            exit(0)
                    else:
                        message = sys.stdin.readline()
                        self.__client.send(message)
                        inputflag()
    
    
    
    #主程序入口
    if __name__ == "__main__":
        client = TalkClient(test_addr,test_port)
        client.running()
    
    

    效果如下图

  • 相关阅读:
    ASP.NET 4.0 与 Entity Framework 4第四篇Entity Framework在三层架构中的使用
    ASP.NET 4.0 与 Entity Framework 4第一篇采用ModelFirst 开发方式创建数据库
    ASP.NET 4.0 与 Entity Framework 4第二篇使用Entity Framework 进行CRUD操作
    ASP.NET 4.0 与 Entity Framework 4第三篇使用Entity Framework调用存储过程
    Unity3D4.* NGUI制作动态字库
    Unity3D内存释放
    1112 Stucked Keyboard (20 分)(map)【回顾】
    1116 Come on! Let's C (20 分)(hash散列)
    1108 Finding Average (20 分)(字符串处理)
    1113 Integer Set Partition (25 分)(排序)
  • 原文地址:https://www.cnblogs.com/KevinGeorge/p/8660051.html
Copyright © 2011-2022 走看看