Skip to content

Instantly share code, notes, and snippets.

@jonnung
Last active September 7, 2017 02:54
Show Gist options
  • Select an option

  • Save jonnung/a6bea2476274069b2a4a to your computer and use it in GitHub Desktop.

Select an option

Save jonnung/a6bea2476274069b2a4a to your computer and use it in GitHub Desktop.
socket, select 모듈을 사용한 TCP 서버/클라이언트 채팅 프로그램
# -*- coding: utf8 -*-
# socket 모듈을 임포트
from socket import *
from select import select
import sys
# 호스트, 포트와 버퍼 사이즈를 지정
HOST = '127.0.0.1'
PORT = 56789
BUFSIZE = 1024
ADDR = (HOST, PORT)
# 소켓 객체를 만들고
clientSocket = socket(AF_INET, SOCK_STREAM)
# 서버와의 연결을 시도
try:
clientSocket.connect(ADDR)
except Exception as e:
print('채팅 서버(%s:%s)에 연결 할 수 없습니다.' % ADDR)
sys.exit()
print('채팅 서버(%s:%s)에 연결 되었습니다.' % ADDR)
def prompt():
sys.stdout.write('<나> ')
sys.stdout.flush()
# 무한 루프를 시작
while True:
try:
connection_list = [sys.stdin, clientSocket]
read_socket, write_socket, error_socket = select(connection_list, [], [], 10)
for sock in read_socket:
if sock == clientSocket:
data = sock.recv(BUFSIZE)
if not data:
print('채팅 서버(%s:%s)와의 연결이 끊어졌습니다.' % ADDR)
clientSocket.close()
sys.exit()
else:
print('%s' % data) # 메세지 시간은 서버 시간을 따른다
prompt()
else:
message = sys.stdin.readline()
clientSocket.send(message)
prompt()
except KeyboardInterrupt:
clientSocket.close()
sys.exit()
# -*- coding: utf8 -*-
# socket 과 select 모듈 임포트
from socket import *
from select import *
import sys
from time import ctime
# 호스트, 포트와 버퍼 사이즈를 지정
HOST = ''
PORT = 56789
BUFSIZE = 1024
ADDR = (HOST, PORT)
# 소켓 객체를 만들고..
serverSocket = socket(AF_INET, SOCK_STREAM)
# 서버 정보를 바인딩
serverSocket.bind(ADDR)
# 요청을 기다림(listen)
serverSocket.listen(10)
connection_list = [serverSocket]
print('==============================================')
print('채팅 서버를 시작합니다. %s 포트로 접속을 기다립니다.' % str(PORT))
print('==============================================')
# 무한 루프를 시작
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]))
# 클라이언트로 응답을 돌려줌
for socket_in_list in connection_list:
if socket_in_list != serverSocket and socket_in_list != sock:
try:
socket_in_list.send('[%s] 새로운 방문자가 대화방에 들어왔습니다. 반가워요~ 짝짝짝!' % ctime())
except Exception as e:
socket_in_list.close()
connection_list.remove(socket_in_list)
# 접속한 사용자(클라이언트)로부터 새로운 데이터 받음
else:
data = sock.recv(BUFSIZE)
if data:
print('[INFO][%s] 클라이언트로부터 데이터를 전달 받았습니다.' % ctime())
for socket_in_list in connection_list:
if socket_in_list != serverSocket and socket_in_list != sock:
try:
socket_in_list.send('[%s] %s' % (ctime(), data))
print('[INFO][%s] 클라이언트로 데이터를 전달합니다.' % ctime())
except Exception as e:
print(e.message)
socket_in_list.close()
connection_list.remove(socket_in_list)
continue
else:
connection_list.remove(sock)
sock.close()
print('[INFO][%s] 사용자와의 연결이 끊어졌습니다.' % ctime())
except KeyboardInterrupt:
# 부드럽게 종료하기
serverSocket.close()
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment