Advertisement
Guest User

Untitled

a guest
Jun 18th, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.72 KB | None | 0 0
  1. //서버
  2. '''
  3. server_socket(arg)
  4. server_socket(a, b)
  5. server_socket(1 + 1)
  6.  
  7. 함수 문자열 인자 : ''
  8. 출력 문자열 인자 : ""
  9. '''
  10.  
  11. import socketserver
  12. import threading
  13.  
  14. HOST = ''
  15.  
  16. PORT = 9009
  17.  
  18. lock = threading.Lock() # syncronized 동기화 진행하는 스레드 생성
  19.  
  20.  
  21.  
  22. class UserManager: # 사용자관리 및 채팅 메세지 전송을 담당하는 클래스
  23.  
  24.                    # ① 채팅 서버로 입장한 사용자의 등록
  25.  
  26.                    # ② 채팅을 종료하는 사용자의 퇴장 관리
  27.  
  28.                    # ③ 사용자가 입장하고 퇴장하는 관리
  29.  
  30.                    # ④ 사용자가 입력한 메세지를 채팅 서버에 접속한 모두에게 전송
  31.  
  32.  
  33.  
  34.    def __init__(self):
  35.  
  36.       self.users = {} # 사용자의 등록 정보를 담을 사전 {사용자 이름:(소켓,주소),...}
  37.  
  38.  
  39.  
  40.    def addUser(self, username, conn, addr): # 사용자 ID를 self.users에 추가하는 함수
  41.  
  42.       if username in self.users: # 이미 등록된 사용자라면
  43.  
  44.          conn.send('이미 등록된 사용자입니다.\n'.encode())
  45.  
  46.          return None
  47.  
  48.  
  49.  
  50.       # 새로운 사용자를 등록함
  51.  
  52.       lock.acquire() # 스레드 동기화를 막기위한 락
  53.  
  54.       self.users[username] = (conn, addr)
  55.  
  56.       lock.release() # 업데이트 후 락 해제
  57.  
  58.  
  59.  
  60.       self.sendMessageToAll('[%s]님이 입장했습니다.' %username)
  61.  
  62.       print('+++ 대화 참여자 수 [%d]' %len(self.users))
  63.  
  64.          
  65.  
  66.       return username
  67.  
  68.  
  69.  
  70.    def removeUser(self, username): #사용자를 제거하는 함수
  71.  
  72.       if username not in self.users:
  73.  
  74.          return
  75.  
  76.  
  77.  
  78.       lock.acquire()
  79.  
  80.       del self.users[username]
  81.  
  82.       lock.release()
  83.  
  84.  
  85.  
  86.       self.sendMessageToAll('[%s]님이 퇴장했습니다.' %username)
  87.  
  88.       print('--- 대화 참여자 수 [%d]' %len(self.users))
  89.  
  90.  
  91.  
  92.    def messageHandler(self, username, msg): # 전송한 msg를 처리하는 부분
  93.  
  94.       if msg[0] != '/': # 보낸 메세지의 첫문자가 '/'가 아니면
  95.  
  96.          self.sendMessageToAll('[%s] %s' %(username, msg))
  97.  
  98.          return
  99.  
  100.  
  101.  
  102.       if msg.strip() == '/quit': # 보낸 메세지가 'quit'이면
  103.  
  104.          self.removeUser(username)
  105.  
  106.          return -1
  107.  
  108.  
  109.  
  110.    def sendMessageToAll(self, msg):
  111.  
  112.       for conn, addr in self.users.values():
  113.  
  114.          conn.send(msg.encode())
  115.  
  116.            
  117.  
  118.  
  119.  
  120. class MyTcpHandler(socketserver.BaseRequestHandler):
  121.  
  122.    userman = UserManager()
  123.  
  124.      
  125.  
  126.    def handle(self): # 클라이언트가 접속시 클라이언트 주소 출력
  127.  
  128.       print('[%s] 연결됨' %self.client_address[0])
  129.  
  130.  
  131.  
  132.       try:
  133.  
  134.          username = self.registerUsername()
  135.  
  136.          msg = self.request.recv(1024)
  137.  
  138.          while msg:
  139.  
  140.             print(msg.decode())
  141.  
  142.             if self.userman.messageHandler(username, msg.decode()) == -1:
  143.  
  144.                self.request.close()
  145.  
  146.                break
  147.  
  148.             msg = self.request.recv(1024)
  149.  
  150.                  
  151.  
  152.       except Exception as e:
  153.  
  154.          print(e)
  155.  
  156.  
  157.  
  158.       print('[%s] 접속종료' %self.client_address[0])
  159.  
  160.       self.userman.removeUser(username)
  161.  
  162.  
  163.  
  164.    def registerUsername(self):
  165.  
  166.       while True:
  167.  
  168.          self.request.send('로그인ID:'.encode())
  169.  
  170.          username = self.request.recv(1024)
  171.  
  172.          username = username.decode().strip()
  173.  
  174.          if self.userman.addUser(username, self.request, self.client_address):
  175.  
  176.             return username
  177.  
  178.  
  179.  
  180. class ChatingServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
  181.  
  182.     pass
  183.  
  184.          
  185.  
  186. def runServer():
  187.  
  188.    print('+++ 채팅 서버를 시작합니다.')
  189.  
  190.    print('+++ 채텅 서버를 끝내려면 Ctrl-C를 누르세요.')
  191.  
  192.  
  193.  
  194.    try:
  195.  
  196.       server = ChatingServer((HOST, PORT), MyTcpHandler)
  197.  
  198.       server.serve_forever()
  199.  
  200.    except KeyboardInterrupt:
  201.  
  202.       print('--- 채팅 서버를 종료합니다.')
  203.  
  204.       server.shutdown()
  205.  
  206.       server.server_close()
  207.  
  208.  
  209.  
  210. runServer()
  211. //서버
  212.  
  213. //클라
  214. import socket
  215.  
  216. from threading import Thread
  217.  
  218.  
  219.  
  220. HOST = 'localhost'
  221.  
  222. PORT = 9009
  223.  
  224.  
  225.  
  226. def rcvMsg(sock):
  227.  
  228.    while True:
  229.  
  230.       try:
  231.  
  232.          data = sock.recv(1024)
  233.  
  234.          if not data:
  235.  
  236.             break
  237.  
  238.          print(data.decode())
  239.  
  240.       except:
  241.  
  242.          pass
  243.  
  244.  
  245.  
  246. def runChat():
  247.  
  248.    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
  249.  
  250.       sock.connect((HOST, PORT))
  251.  
  252.       t = Thread(target=rcvMsg, args=(sock,))
  253.  
  254.       t.daemon = True
  255.  
  256.       t.start()
  257.  
  258.  
  259.  
  260.       while True:
  261.  
  262.          msg = input()
  263.  
  264.          if msg == '/quit':
  265.  
  266.             sock.send(msg.encode())
  267.  
  268.             break
  269.  
  270.  
  271.  
  272.          sock.send(msg.encode())
  273.  
  274.              
  275.  
  276. runChat()
  277.  
  278. // 클라
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement