서버¶
- 문자열 송신, 직렬화된 오브젝트 수신 # 클라이언트
- 문자열 수신, 오브젝트 직렬화 및 송신
- 한 이용자가 보낸 메시지 -> 접속된 모든 이용자에게 전달
- 중지 되지 않는 서버 작성
- 무한히 클라이언트 대기 기능
- 서버에 쓰레드 도입
- 대기용 쓰레드 while True:
csock, addr = serverSock.accept() t1 = thearding.Thread(xxxxxxxxxxx) t1.start()
- 송수신 쓰레드
- # 채팅프로그램
- Network CRUD ( 이용자 (User) 정보 네트워크 입출력 시스템)
- num, name, phone, email
- 클라이언트가 서버에 접속하면 CRUD를 위한 메뉴를 보여준다
- 클라이너트가 입력한 객체는 직렬화하여 서버로 전달한다
- [추가] 기능 구현
List Comprehension¶
for i in range(5):
pass
nems=[] for i in range(5): nums.append(i) nums
[i for i in range(5)]
[i if i%2==0 else 0 for i in range(10)]
In [1]:
class MsgObj:
def __init__(self, req, res):
self.req = req
self.res = res
In [2]:
class User:
def __init__(self,num,name=None,phone=None,email=None):
self.num = num
self.name = name
self.phone = phone
self.email = email
def __str__(self):
return f'{self.num}\t{self.name}\t{self.phone}\t{self.email}'
def __eq__(self, other):
return True if self.num==other.num else False
In [3]:
import threading
class ServerCommThread(threading.Thread):
def __init__(self, sock, addr):
threading.Thread.__init__(self)
self.sock = sock
self.addr = addr
self.menuList = "목록(s) 추가(a) 검색(f) 수정(u) 삭제(d) 종료(x):"
self.fname = 'C:/test/userList.pickle'
def run(self):
while True:
msg = self.menuList
self.sock.send(msg.encode('utf-8')) # 바이트 단위로 전송됨(문자열 이외도 가능)
userMenu = self.sock.recv(1024).decode('utf-8') # 이용자가 선택한 메뉴
print("userMenu:"+userMenu)
if userMenu=='a':
self.add()
elif userMenu=='s':
self.send_list(self.list())
elif userMenu=='f':
self.find()
elif userMenu=='u':
self.update()
elif userMenu=='d':
self.delete()
else:
print("Debug:"+userMenu)
def find(self):
msg = '검색할 이용자 번호:'
self.sock.send(msg.encode('utf-8'))
num = self.sock.recv(1024)
userList = self.get_list()
idx = userList.index(User(num.decode('utf-8')))
self.sock.send(pickle.dumps(userList[idx]))
def add(self):
msg = "번호 이름 전화 이메일:"
self.sock.send(msg.encode('utf-8'))
user_bytes = self.sock.recv(1024*10)
userObj = pickle.loads(user_bytes)
print('서버에 전달된 데이터:', userObj)
userList = self.get_list()
userList.append(userObj)
self.save_list(userList)
print('서버측 파일에 저장')
msgObj = MsgObj("a", True)
self.sock.send(pickle.dumps(msgObj))
def send_list(self):
userList = self.get_list()
self.sock.send(pickle.dumps(userList))
def get_list(self):
try:
with open(self.fname, 'rb') as file:
userList = pickle.load(file)
return userList
except:
with open(self.fname, 'wb') as file:
return []
def save_list(self, userList):
with open(self.fname, 'wb') as file:
pickle.dump(userList, file)
In [ ]:
from socket import *
import time
import pickle
import threading
serverSock = socket(AF_INET, SOCK_STREAM)
serverSock.bind(('', 1122)) # 1024 이후의 포트번호
serverSock.listen()
while True:
print('서버 대기중...')
clientSock, addr = serverSock.accept()
print(str(addr), '클라이언트 접속됨')
commThread = ServerCommThread(clientSock, addr)
commThread.start()
print('서버 종료')
서버 대기중...
('127.0.0.1', 56831) 클라이언트 접속됨
서버 대기중...
userMenu:a
서버에 전달된 데이터: 13 Blake 010-2541-2690 blake@gmail.com
서버측 파일에 저장
In [1]:
class MsgObj:
def __init__(self, req, res):
self.req = req
self.res = res
In [2]:
class User:
def __init__(self,num,name,phone,email):
self.num = num
self.name = name
self.phone = phone
self.email = email
def __str__(self):
return f'{self.num}\t{self.name}\t{self.phone}\t{self.email}'
def __eq__(self, other):
return True if self.num==other.num else False
In [ ]:
# Client
from socket import *
import pickle
import time
clientSock = socket(AF_INET, SOCK_STREAM)
clientSock.connect(('127.0.0.1', 1122))
def add():
clientSock.send(userMenu.encode('utf-8')) # 클라이언트가 선택한 메뉴를 서버에 전달
# 서버측에서 전달된 데이터 : 번호 이름 전화 이메일
itemsToInput = clientSock.recv(1024)
sIn = input(itemsToInput.decode('utf-8'))
[num,name,phone,email] = sIn.split()
uInfo = User(num,name,phone,email)
user_bytes = pickle.dumps(uInfo)
clientSock.send(user_bytes)
msg_bytes = clientSock.recv(1024)
msgObj = pickle.loads(msg_bytes)
print('사용자 정보 추가 성공' if msgObj.res else '사용자 정보 추가 실패')
def req_list():
pass
def find():
pass
def update():
pass
def delete():
pass
while True:
menuList = clientSock.recv(1024) #
userMenu = input(menuList.decode('utf-8')) # 메뉴 보여주기
if userMenu=='a':
add()
elif userMenu=='s':
req_list()
elif userMenu=='f':
find()
elif userMenu=='u':
update()
elif userMenu=='d':
delete()
elif userMenu=='x':
break
print('클라이언트 종료')
목록(s) 추가(a) 검색(f) 수정(u) 삭제(d) 종료(x):a
번호 이름 전화 이메일:13 Blake 010-2541-2690 blake@gmail.com
사용자 정보 추가 성공
In [ ]:
Server¶
In [1]:
class MsgObj:
def __init__(self,num,msg):
self.num=num
self.msg=msg
def __str__(self):
return f'{self.num}\t{self.msg}'
In [2]:
class User:
def __init__(self,num,name,phone,email):
self.num=num
self.name=name
self.phone=phone
self.email=email
def __str__(self):
return f'{self.num}\t{self.name}\t{self.phone}\t{self.email}'
def __eq__(self):
return True if self.num==other.num else False
In [3]:
# 통신 준비
from socket import * #socket.xxx
import time
import pickle
import threading
serverSock=socket(AF_INET,SOCK_STREAM)
serverSock.bind(('',1122)) # 1024 이후의 포트번호 이전은 많은 서버들이 이미 사용중
serverSock.listen()
#menuList="메뉴: [추가:a]"
In [4]:
# #commThread = threading.Thread(target=comm,args=(clientSock,addr))
# #commThread.start()
# commThread = ServerCommThread(clientSock, addr)
# commThread.start()
# 로 교체한부분
import threading
class ServerCommThread(threading.Thread):
def __init__(self,sock, addr):
threading.Thread.__init__(self)
self.sock=sock
self.addr=addr
self.menuList="[목록:s] [추가:a] [검색:f] [수정:u] [삭제:d] [종료:x] --->"
def run(self):
msg =self.menuList
self.sock.send(msg.encode('utf-8')) #바이트 단위로 전송됨(문자열 이외도 가능) 클라이언트가 수신상태여야 수신 가능하다
userMenu=self.sock.recv(1024).decode('utf-8') #이용자가 선택한 메뉴
print("userMunu : "+userMenu)
if userMenu=='a':
self.add()
elif userMenu=='s':
self.show()
elif userMenu=='f':
pass
elif userMenu=='u':
pass
elif userMenu=='d':
pass
elif userMenu=='x':
pass
def add(self):
msg="번호 이름 전화 이메일:"
self.sock.send(msg.encode('utf-8'))
user_bytes = self.sock.recv(1024*10)
userObj=pickle.loads(user_bytes)
print('서버에 전달된 데이터:',userObj)
with open('/Users/lucas/test/userList.pickle','wb') as file:
pickle.dump([userObj],file)
print('서버측 파일에 저장')
def load(self):
with open('/Users/lucas/test/userList.pickle','rb') as file:
return pickle.load(file)
def show(self):
loadList=self.load()
pickleList=pickle.dumps(loadList)
self.sock.send(pickleList)
In [ ]:
'''
def comm(sock,addr):
# 문자열 송신 , 계속해서 접속자를 받아주어야 한다. 따라서 Thead+while
msg = menuList
sock.send(msg.encode('utf-8')) #바이트 단위로 전송됨(문자열 이외도 가능) 클라이언트가 수신상태여야 수신 가능하다
userMenu=sock.recv(1024).decode('utf-8') #이용자가 선택한 메뉴
print("userMunu : "+userMenu)
if userMenu=='a':
msg="번호 이름 전화 이메일:"
sock.send(msg.encode('utf-8'))
user_bytes = sock.recv(1024*10)
userObj=pickle.loads(user_bytes)
print('서버에 전달된 데이터:',userObj)
with open('/Users/lucas/test/userList.pickle','wb') as file:
pickle.dump([userObj],file)
print('서버측 파일에 저장')
else:
print("Debug"+userMenu)
'''
while True: # 1. 중지 되지 않는 서버 작성 * 무한히 클라이언트 대기 기능
print('서버 대기중...') #실헹하면 보안경고창 표시됨, 액세스 허용
clientSock, addr = serverSock.accept() #튜플 리턴 (clentSock,addre)생략 [주소]
print(str(addr),'클라이언트 접속됨')
#commThread = threading.Thread(target=comm,args=(clientSock,addr))
#commThread.start()
commThread = ServerCommThread(clientSock, addr)
commThread.start()
# time.sleep(1) #기다림 없이 서버가 끝나버려서 수신이 안될수 있다.추후 무한루프로 인해 삭제할것임
print('서버 종료')
서버 대기중...
('127.0.0.1', 62168) 클라이언트 접속됨
서버 대기중...
userMunu : s
('127.0.0.1', 62298) 클라이언트 접속됨
서버 대기중...
userMunu : s
('127.0.0.1', 62364) 클라이언트 접속됨
서버 대기중...
userMunu : s
('127.0.0.1', 62560) 클라이언트 접속됨
서버 대기중...
userMunu : s
In [1]:
class MsgObj:
def __init__(self, req, res):
self.req = req
self.res = res
In [2]:
class User:
def __init__(self,num,name=None,phone=None,email=None):
self.num = num
self.name = name
self.phone = phone
self.email = email
def __str__(self):
return f'{self.num}\t{self.name}\t{self.phone}\t{self.email}'
def __eq__(self, other):
return True if self.num==other.num else False
In [3]:
import threading
class ServerCommThread(threading.Thread):
def __init__(self, sock, addr):
threading.Thread.__init__(self)
self.sock = sock
self.addr = addr
self.menuList = "목록(s) 추가(a) 검색(f) 수정(u) 삭제(d) 종료(x):"
self.fname = 'C:/test/userList.pickle'
def run(self):
while True:
msg = self.menuList
self.sock.send(msg.encode('utf-8')) # 바이트 단위로 전송됨(문자열 이외도 가능)
userMenu = self.sock.recv(1024).decode('utf-8') # 이용자가 선택한 메뉴
print("userMenu:"+userMenu)
if userMenu=='a':
self.add()
elif userMenu=='s':
self.send_list(self.list())
elif userMenu=='f':
self.find()
elif userMenu=='u':
self.update()
elif userMenu=='d':
self.delete()
else:
print("Debug:"+userMenu)
def find(self):
msg = '검색할 이용자 번호:'
self.sock.send(msg.encode('utf-8'))
num = self.sock.recv(1024)
userList = self.get_list()
idx = userList.index(User(num.decode('utf-8')))
self.sock.send(pickle.dumps(userList[idx]))
def add(self):
msg = "번호 이름 전화 이메일:"
self.sock.send(msg.encode('utf-8'))
user_bytes = self.sock.recv(1024*10)
userObj = pickle.loads(user_bytes)
print('서버에 전달된 데이터:', userObj)
userList = self.get_list()
userList.append(userObj)
self.save_list(userList)
print('서버측 파일에 저장')
msgObj = MsgObj("a", True)
self.sock.send(pickle.dumps(msgObj))
def send_list(self):
userList = self.get_list()
self.sock.send(pickle.dumps(userList))
def get_list(self):
try:
with open(self.fname, 'rb') as file:
userList = pickle.load(file)
return userList
except:
with open(self.fname, 'wb') as file:
return []
def save_list(self, userList):
with open(self.fname, 'wb') as file:
pickle.dump(userList, file)
In [ ]:
from socket import *
import time
import pickle
import threading
serverSock = socket(AF_INET, SOCK_STREAM)
serverSock.bind(('', 1122)) # 1024 이후의 포트번호
serverSock.listen()
while True:
print('서버 대기중...')
clientSock, addr = serverSock.accept()
print(str(addr), '클라이언트 접속됨')
commThread = ServerCommThread(clientSock, addr)
commThread.start()
print('서버 종료')
서버 대기중...
('127.0.0.1', 56831) 클라이언트 접속됨
서버 대기중...
userMenu:a
서버에 전달된 데이터: 13 Blake 010-2541-2690 blake@gmail.com
서버측 파일에 저장
In [1]:
class MsgObj:
def __init__(self, req, res):
self.req = req
self.res = res
In [2]:
class User:
def __init__(self,num,name,phone,email):
self.num = num
self.name = name
self.phone = phone
self.email = email
def __str__(self):
return f'{self.num}\t{self.name}\t{self.phone}\t{self.email}'
def __eq__(self, other):
return True if self.num==other.num else False
In [ ]:
# Client
from socket import *
import pickle
import time
clientSock = socket(AF_INET, SOCK_STREAM)
clientSock.connect(('127.0.0.1', 1122))
def add():
clientSock.send(userMenu.encode('utf-8')) # 클라이언트가 선택한 메뉴를 서버에 전달
# 서버측에서 전달된 데이터 : 번호 이름 전화 이메일
itemsToInput = clientSock.recv(1024)
sIn = input(itemsToInput.decode('utf-8'))
[num,name,phone,email] = sIn.split()
uInfo = User(num,name,phone,email)
user_bytes = pickle.dumps(uInfo)
clientSock.send(user_bytes)
msg_bytes = clientSock.recv(1024)
msgObj = pickle.loads(msg_bytes)
print('사용자 정보 추가 성공' if msgObj.res else '사용자 정보 추가 실패')
def req_list():
pass
def find():
pass
def update():
pass
def delete():
pass
while True:
menuList = clientSock.recv(1024) #
userMenu = input(menuList.decode('utf-8')) # 메뉴 보여주기
if userMenu=='a':
add()
elif userMenu=='s':
req_list()
elif userMenu=='f':
find()
elif userMenu=='u':
update()
elif userMenu=='d':
delete()
elif userMenu=='x':
break
print('클라이언트 종료')
목록(s) 추가(a) 검색(f) 수정(u) 삭제(d) 종료(x):a
번호 이름 전화 이메일:13 Blake 010-2541-2690 blake@gmail.com
사용자 정보 추가 성공
In [ ]:
'자바~하둡' 카테고리의 다른 글
R) 데이터 준비 (0) | 2022.03.06 |
---|---|
R) 데이터 자료구조 별 indexing (0) | 2022.03.03 |
python) Thread pickle socket (0) | 2022.02.24 |
python) File IO _CRUD (1) | 2022.02.23 |
python) List Tuple Set Dictionary 클레스 File IO (0) | 2022.02.22 |