Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

소켓 랜덤채팅 본문

Study/Python

소켓 랜덤채팅

awakerrday 2017. 7. 3. 02:21


Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# -*- coding:utf-8 -*-
# socket 과 select 모듈 임포트
from socket import *
from select import *
import sys, thread, threading
from time import ctime
from collections import deque
 
class UserInfo():
    def __init__(self):
        self.name_list = []
        self.socket_dic = {}
        self.addr_dic = {}
    
    def addInfo(self, name, socket, ADDR):
        self.name_list.append(name)
        self.socket_dic[name] = socket
        self.addr_dic[name] = ADDR
 
    def getSocket(self, name):
        return self.socket_dic[name]
 
    def getAddr(self, name):
        return self.addr_dic[name]
 
    def remove(self, name):
        self.name_list.remove(name)
        del self.socket_dic[name]
        del self.addr_dic[name]
 
class ChatRoom(threading.Thread):                       # Thread 객체 상속, ChatRoom 클래스 정의
    def __init__(self, n, c1, c2, userinfo, cnames):
        threading.Thread.__init__(self)
        self.room_number = n
        self.userinfo = userinfo
        self.cnames = cnames
        self.connection_list = [c1, c2]
 
    def run(self):                                      # run 메소드 정의 
 
        while len(self.connection_list)==2:
            read_socket, write_socket, error_socket = select(self.connection_list, [], [], 10)
            
            for sock in read_socket:
 
                from_name = 'Unknown'
                for cname in self.cnames:
                    if userinfo.getSocket(cname) == sock:
                        from_name = cname
 
                data = sock.recv(BUFSIZE)
                print(data)
 
                if data == 'quit':
                    self.connection_list.remove(sock)
                    self.cnames.remove(from_name)
                    userinfo.remove(from_name)
                    sock.close()
                    sock = None
                    waiting_queue.append(self.cnames[0])
                    userinfo.getSocket(self.cnames[0]).send('[INFO] 상대가 대화방을 나갔습니다. 새로운 상대를 기다립니다.')
                    print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), from_name))
                    break
                          
                elif data:
                    print('[INFO][%d][%s] %s 클라이언트로부터 데이터를 전달 받았습니다.' %(self.room_number, from_name, ctime()))
 
                    for cname in cnames:
                        if userinfo.getSocket(cname) != sock:
                            socket_in_list = userinfo.getSocket(cname)
 
                            try:
                                socket_in_list.send('<%s (상대)> %s      [%20s]' % (from_name, data, ctime()))
                                print('[INFO][%d][%s] 클라이언트로 데이터를 전달합니다.' %(self.room_number, ctime()))
 
                            except Exception as e:
                                print(e.message)
                                socket_in_list.close()
                                self.connection_list.remove(socket_in_list)
                                cnames.remove(cname)
                                continue
                else:
                    self.connection_list.remove(sock)
                    if userinfo.getSocket(cnames[0]) == sock:
                        cnames.remove(cnames[0])
                        sock.close()
                        sock = None
                        print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), cnames[0]))
                    else:
                        cnames.remove(cnames[1])
                        sock.close()
                        sock = None
                        print('[INFO][%s] %s와의 연결이 끊어졌습니다.' % (ctime(), cnames[1]))
        
        print(room_threads)
        print('[INFO] %d chatroom thread done!!' %self.room_number)
        del room_threads[self.room_number]
        print(room_threads)
 
 
 
def handler(sysin):                 # exit 입력을 처리할 핸들러
    while 1:
        message = sysin.readline()
        if(message == "exit\n"):
            try:
                for th in room_threads:
                    th.join()
                connection_list.pop()
                sys.exit() 
            except SystemExit:
                print("SERVER EXIT")
            except:
                print("Something went horribly wrong")    
 
 
# 호스트, 포트와 버퍼 사이즈를 지정
HOST = ''
PORT = 1614
BUFSIZE = 1024
ADDR = (HOST, PORT)
room_i = 0
 
# 소켓 객체를 만들고..
serverSocket = socket(AF_INET, SOCK_STREAM)
 
# 서버 정보를 바인딩
serverSocket.bind(ADDR)
 
# 요청을 기다림(listen)
serverSocket.listen(10)
connection_list = [serverSocket]
waiting_queue = deque()
room_threads = {}
 
userinfo = UserInfo()
print('==============================================')
print('채팅 서버를 시작합니다. %s 포트로 접속을 기다립니다.' % str(PORT))
print('==============================================')
 
in_thread = thread.start_new_thread(handler, (sys.stdin, ))
 
# 무한 루프를 시작`                                                                                                            
while connection_list:
    try:
        print('[INFO] 요청을 기다립니다...')
 
        # select 로 요청을 받고, 10초마다 블럭킹을 해제하도록 함
        read_socket, write_socket, error_socket = select(connection_list, [], [], 10)
 
        for sock in read_socket:
            # 새로운 접속
            if sock == serverSocket:
                clientSocket, addr_info = serverSocket.accept()
                #connection_list.append(clientSocket)
                
                print('[INFO][%s] 클라이언트(%s)가 새롭게 연결 되었습니다.' % (ctime(), addr_info[0]))
                name = clientSocket.recv(20)
                userinfo.addInfo(name, clientSocket, addr_info)
 
                if (len(waiting_queue) < 1):
                    waiting_queue.append(name)
                    print(waiting_queue)
                    print('[INFO] 대화상대를 찾고있습니다.')
                    clientSocket.send('[INFO] 대화상대를 찾고있습니다.')
                else:
                    waiting_queue.append(name)
                    print('[INFO] 대화상대를 찾고있습니다.')
                    clientSocket.send('[INFO] 대화상대를 찾고있습니다.\n')
 
                    clients = []
                    cnames = []
                    for wname in waiting_queue:
                        if (len(clients) <= 1):
                            clients.append([userinfo.getSocket(wname), userinfo.getAddr(wname)])
                            cnames.append(wname)
 
                    try:
                        room_i += 1
                        
                        clients[0][0].send('[%s] %s님과 %s님의 대화방입니다.' %(ctime(), cnames[0], cnames[1]))
                        clients[1][0].send('[%s] %s님과 %s님의 대화방입니다.' %(ctime(), cnames[1], cnames[0]))
                        chatroom = ChatRoom(room_i, clients[0][0], clients[1][0], userinfo, cnames)
                        chatroom.start()
                        room_threads[room_i] = chatroom
 
                        waiting_queue.clear()
                    except Exception as e:
                        clients[0][0].close()
                        clients[1][0].close()
                        waiting_queue.clear()
 
    except KeyboardInterrupt:
        # 부드럽게 종료하기
        serverSocket.close()
        sys.exit()
cs



Client

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# -*- coding:utf-8 -*-
# socket 모듈을 임포트
from socket import *
from select import select
import sys, thread, time
 
 
# 호스트, 포트와 버퍼 사이즈를 지정
HOST = ''
PORT = 1614
BUFSIZE = 1024
ADDR = (HOST, PORT)
name = 'Unknown'
recv_check=0
 
def handler():
    while 1:
        message = raw_input()
        if(message == ""):
            prompt()
            message = raw_input()
            if(message == "quit"):
                try:
                    clientSocket.send('quit')
                    clientSocket.close()
                    sys.exit()
                except SystemExit:
                    print("프로그램을 종료합니다.")
                except:
                    print("Something went horribly wrong")   
            clientSocket.send(message)
 
def prompt():
    sys.stdout.write('<'+name+ '(나)> ')
    sys.stdout.flush()
 
# 소켓 객체를 만들고
clientSocket = socket(AF_INET, SOCK_STREAM)
 
# 서버와의 연결을 시도
try:
    clientSocket.connect(ADDR)
except Exception as e:
    print('채팅 서버에 연결 할 수 없습니다.')
    sys.exit()
print('채팅 서버에 연결 되었습니다.')
name = raw_input('닉네임을 입력하세요 : ')
 
clientSocket.send(name)
 
in_thread = thread.start_new_thread(handler, ( ))
 
# 무한 루프를 시작
while True:
    try:
        recv_check=0
        connection_list = [clientSocket]
 
        read_socket, write_socket, error_socket = select(connection_list, [], [], 10)
 
        for sock in read_socket:
            if sock == clientSocket:
                data = sock.recv(BUFSIZE)
                recv_check = 1
                if not data:
                    print('채팅 서버와의 연결이 끊어졌습니다.')
                    clientSocket.close()
                    sys.exit()
 
                else:
                    print('%s' % data)  # 메세지 시간은 서버 시간을 따른다
                    if(data != '[INFO] 대화상대를 찾고있습니다.' and recv_check==0):
                        prompt()
 
    except KeyboardInterrupt:
        clientSocket.close()
        sys.exit()
 
cs


'Study > Python' 카테고리의 다른 글

코드 인젝션 활용  (0) 2017.07.09
윈도우 DEP 우회  (0) 2017.07.03
PyDbg 접근 위반 핸들  (0) 2017.07.03
윈도우 디버거 구현  (0) 2017.07.03
ctypes 파이썬 외부 함수 라이브러리  (0) 2017.06.13
Comments