首页 > 技术文章 > socket 实现一个类似简单聊天室的功能(多客户端互相通信)

xiaoxiao075 2019-03-11 16:54 原文

server端:

#coding=utf-8
'''
一个广播程序,linux运行
'''
import select,socket

import traceback



def broadcast(conn,message):
    for i in conn_list:
        if i!=sk and i!=conn:
            try:
                i.send(message.encode())
            except:
                conn.close()
                conn_list.remove(i)


if __name__=='__main__':
    conn_list=[]
    buffer_size=4096
    
    sk=socket.socket()
    sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    sk.bind(('127.0.0.1',9789))
    sk.listen(5)
    conn_list.append(sk)
    print('Chat server started on port 9789')

    while 1:
        print('while wai: mission list:',conn_list)
        read_sock,write_sock,error_sock=select.select(conn_list,[],[])
        for i in read_sock:
            print('for mission list:',conn_list)
            if i==sk:
                conn,addr=sk.accept()
                conn_list.append(conn)
                print('client (%s,%s) connected'%addr)

                print('socket server broadcast now!')
                broadcast(conn,'(%s,%s) entered room '%addr)
            
            else:
                try:
                    data=i.recv(4096) #buffer_size
                    
                    if data:
                        print('recv data:',data.decode())
                        print('received from conn broadcast2 now!')
                        broadcast(i,'from client %s:'%str(i.getpeername())+data.decode()+'\n')

                    elif data.strip()=='' or data.strip()=='bye':
                        print('client %s close!'%str(i.getpeername()))
                        i.close()
                        conn_list.remove(i)
                        break
                    else:
                        print('client %s close!'%str(i.getpeername())) 
                        i.close()
                        conn_list.remove(i)
                        break
                    
                except:
                    traceback.print_exc()
                    print('%s is offline!'%str(i.getpeername()))
                    i.close()
                    conn_list.remove(i)
                    #continue
                    break
    sk.close()

 

client端:

#coding=utf-8
'''
client
'''

import socket,select,string,sys

def prompt():
    #sys.stdout.write('<You>')
    #sys.stdout.flush()
    print('<You>')

if __name__=='__main__':
    '''
    if len(sys.argv)<3:
        print('参数错误!')
        sys.exit()
    
    host=sys.argv[1]
    port=int(sys.argv[2])
    '''

    sk=socket.socket()
    try:
        #sk.connect((host,port))
        sk.connect(('127.0.0.1',9789))
    except:
        print('unable to connect')
        sys.exit()
    
    print('connected success,send message')
    prompt()

    while 1:
        ll=[sys.stdin,sk]
        read_l,write_l,error=select.select(ll,[],[])

        for i in read_l:
            if i==sk:
                data=sk.recv(4096)
                if not data:
                    pass
                    
                else:
                    sys.stdout.write(data.decode())
                    prompt()
            else:
                msg=sys.stdin.readline()
                if not (msg.strip()=='' or msg.strip()=='bye'):
                    sk.send(msg.encode())
                    prompt()
                else:
                    sk.close()
                    ll.clear()
                    break
        if len(ll)==0:
            break
    sys.exit()
    

 

推荐阅读