python下socket编程-3

python下聊天室程序:

服务端:

import socket

import select


class SelectServer(object):
    def __init__(self, host, port, backlog):
        self.addr = (host,port)     #服务端监听的地址
        self.backlog = backlog      #同时连接的个数
        self.socketList = list()    #socket列表,用于select
        self.s = None          #服务端socket

    def runing(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #创建socket
        self.s.bind(self.addr)     #绑定地址
        self.s.listen(self.backlog)    #监听
        self.socketList.append(self.s)     #加入到socket列表
        print("Server start!")          #启动

        while True:
            rlist, wlist, elist = select.select(self.socketList, [], self.socketList)   #select监听
            # select中第1个参数表示self.socketDict.values()中发生变化的句柄放入rlist。
            # select中第2个参数表示[]中的值原封不动的传递给wlist。
            # select中第3个参数表示self.socketDict.values()中发生错误的句柄放入elist
            for r in rlist:
                if r == self.s:    #如果是服务端的socket可读,则说明有新的客户端连接过来
                    serverConn, clienAddr = self.s.accept()    #接收连接
                    self.socketList.append(serverConn)      #加入到列表中
                    print("{0}进入了房间".format(clienAddr))     #打印信息
                    self.sendMsageToOther(self.s, "{0}进入了房间".format(clienAddr))
                else:       #客户端可读,说明有人发送信息
                    try:
                        data = r.recv(2048)     #接收客户端发来的消息
                        if data:
                            self.sendMsageToOther(r, "{0}: {1}".format(clienAddr, data))    #把消息发送到其他客户端
                    except Exception as e:
                        print("{0}下线rrr".format(clienAddr))    #接收失败,说明客户端连接出现问题,断开,并移除
                        self.sendMsageToOther(r, "{0}下线rrr".format(clienAddr))  #下线消息发送到其他客户端
                        r.close()   #关闭连接
                        for i in self.socketList:
                            if i == r:      #移除连接
                                self.socketList.remove(i)

            for e in elist: #发生错误,移除
                e.close()
                for i in self.socketList:   #发生错误的移除
                    if i == e:
                        self.socketList.remove(i)
                        print("{0}下线eee".format(i.getsockname()))
                        self.sendMsageToOther(e, "{0}下线eee".format(i.getsockname()))

    def sendMsageToOther(self, sock, data): #发送消息给其他客户端
        for i in self.socketList:
            if i != sock and i != self.s:
                try:
                    i.sendall(data.encode("utf-8")) #发送
                except: #如果出现错误,则下线
                    self.socketList.remove(i)
                    print("{0}下线sss".format(i.getsockname()))
                    self.sendMsageToOther(i, "{0}下线sss".format(i.getsockname()).encode("utf-8"))
                    i.close()



def main():
    selectServer = SelectServer(host="0.0.0.0", port=6666, backlog=5)
    selectServer.runing()

if __name__ == "__main__":
    main()

 

client端:

import socket

import threading


class SocketInput(threading.Thread):    #开一个输入线程,专门从终端接收数据并通过socket发送到服务端
    def __init__(self,sock):
        super(SocketInput,self).__init__()
        self.sock = sock

    def run(self):
        while True:
            data = input("")    #接收数据
            self.sock.sendall(data.encode("utf-8")) #发送到服务端

class SelectSocketClient(object):
    def __init__(self, host, port):
        self.addr = (host, port)
        self.s = None
        self.input = None

    def runing(self):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  #创建socket

        self.s.connect_ex(self.addr)    #连接
        self.input = SocketInput(self.s)
        self.input.start()  #启动输入

        print("Connected to remote host. Start sending messages")
        while True:
            try:
                data = self.s.recv(2048)
                if not data:
                    continue
                else:
                    print("{0}".format(data.decode("utf-8")))
            except:
                print("server error!!!!")
                self.s.close()
                exit()

if __name__ == "__main__":
    client1 = SelectSocketClient("127.0.0.1", 6666)
    client1.runing()

 

posted @ 2018-01-08 14:56  岁月不可追  阅读(178)  评论(0)    收藏  举报