롸?
소켓과 스레드를 이용한 간단 에코서버, 챗 서버 본문
1-1. 소켓을 이용한 간단 에코 서버.py
import socket
HOST = '127.0.0.1' #호스트를 지정하지 않으면 가능한 모든 인터페이스를 의미
PORT = 9999
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.bind((HOST, PORT))
ss.listen(1) #접속이 있을 때 까지 기다림
conn, addr = ss.accept() #접속을 승인
print('client addr :', addr)
while True:
data = conn.recv(1024).decode() #클라이언트로부터 데이터 수신
if data == 'q':
print('quit connection')
exit()
conn.send(data.encode('utf-8')) #받은 데이터를 그대로 클라이언트에 전송
ss.close()
conn.close()
1-2. 소켓을 이용한 간단 클라이언트.py
import socket
HOST = '127.0.0.1'
PORT = 9999
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect((HOST, PORT)) #server와 연결
while True:
str = input('echo : ')
cs.send(str.encode(encoding='utf_8')) #서버에 데이터 전송
data = cs.recv(1024).decode() #서버로부터 정보를 받음
print('server : ', data)
cs.close()
2-1. 간단한 챗 서버.py
import threading, socket
ss = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ss.bind(('127.0.0.1', 7777))
ss.listen(5)
users = []
def ChatUser(conn):
name = conn.recv(1024)
data = '__' + name.decode('utf-8') + '님 입장__'
print(data)
try:
for p in users:
p.send(data.encode('utf-8'))
while True:
msg = conn.recv(1024)
data = name.decode('utf-8') + ' --> ' + msg.decode('utf-8')
print('server : ', data)
for p in users:
p.send(data.encode('utf-8'))
except:
users.remove(conn) #유저가 종료한 경우
data = '__' + name.decode('utf-8') + '님 퇴장__'
if users:
for p in users:
p.send(data.encode('utf-8'))
else:
print('서버 종료')
while True:
conn, addr = ss.accept()
users.append(conn)
th = threading.Thread(target=ChatUser, args=(conn, ))
th.start() #클라이언트가 들어올때마다 users에 담기고 유저마다 chatuser 스레드를 스타드
2-2. 간단한 챗 클라이언트.py
import threading, socket, sys
def Handle(socket):
while True:
data = socket.recv(1024)
if not data: continue # 데이터가 없는 경우
print(data.decode('utf-8'))
sys.stdout.flush() #버퍼 비우기
name = input('닉네임 입력 :')
cs = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
cs.connect(('127.0.0.1', 7777))
cs.send(name.encode('utf-8')) #대화명 전송
th = threading.Thread(target=Handle, args=(cs, ))
th.start()
while True:
msg = input('>>')
sys.stdout.flush()
if not msg: continue
cs.send(msg.encode('utf-8')) #대화 메세지 전송
cs.close()
3. socket(), bind(), listen()
socket.socket() 함수를 이용해서 소캣 객체를 생성할 수 있다. 이 함수는 두가지 인자를 받는데 하나가 패밀리이고 하나는 타입이다.
패밀리 : 소켓의 패밀리란 "택배상자에 쓰는 주소 체계가 어떻게 되어있냐"에 관한 것으로 흔히 AF_INET나 AF_INET6를 많이 쓴다. AF_INET는 IP4v, AF_INET6는 IP6v에 사용된다.
타입 : 소켓 타입이다. raw 소켓, 스트림 소켓, 데이터그램 소켓 등등이 있는데 주로 많이 쓰는 것은 SOCK_STREAM 와 SOCK_DGRAM이다.
참고
1. 참고 서적 - 빠르게 활용하는 파이썬 3.6 프로그래밍
'프로그래밍 > Python' 카테고리의 다른 글
DB연동 (mariaDB) (0) | 2020.05.13 |
---|---|
파일 입출력 (0) | 2020.05.13 |
모듈 (0) | 2020.05.08 |
클래스 (0) | 2020.05.08 |
함수, lambda (0) | 2020.05.07 |
Comments