이제부터 실용적으로 코드와 실행할 수 있는 프로그램에 대한 이야기를 할 것임
socket( )
= 지금부터 통신 시작!
기본적으로 app 본인이 통신을 하려고 했을 때 OS로부터 포트번호와 같은 숫자들을 가져와야 한다. 함수 호출을 통해 OS가 메모리나 기타 등등 준비하도록 한다.
bind( )
상위계층에서 만들어진 socket과 OS를 연결해서 통신을 개시. 통신하고자 하는 컴퓨터의 IP add , port num을 OS에게 TCP UDP를 써서 설정
listen( )
상대방의 connection request를 listen하는 것
- UDP : 주는대로 받기 -> listen 필요 X
- TCP : conenction oriented기 때문에 연결필요
connect( )
client가 listen하고 있는 server에게 연결 요청을 보내는 것. TCP socket을 통해서 상대방 TCP socket과 connect 하는 것.
accept( )
server가 client의 request를 수락하는 과정. 본인이 임시로 만들었던 socket을 상대방의 정보와 합치는 것. remote client가 전달한 정보와 내 정보를 pair로 조합. 상대방과 내가 연결된 socket을 새롭게 가지게 된다
-> 이것 모두 API 밑에서 벌어지는 일이기 때문에 우리가 직접 관여하지는 않아영
send( ), recv( ), sendto( ), recvfrom( ) 등등
bidirectional하게 정보를 주고받는다.
write( ), read( )
socket을 file로 규정해서 write read하는 것도 가능
close( )
연결 해지하는 부분
유용한 옵션들
setsockopt( ) : 젤 많이 쓰일 것
개발자가 모든 설정을 하기에는 너무 복잡하기 때문에 대부분의 기능을 Socket 밑에서 자동으로 해준다. 개발자가 특정 소켓의 옵션을 건드릴 때 사용. 옵션을 가져오고 싶을 때는 getsocketopt( )
gethostbyname( ) , gethostbyaddr( )
도메인 이름을 숫자로 바꾸거나 IP add를 다시 도메인이름으로 바꾸는 것
select( ), poll( )
C나 C++ 때 쓰일 수도 있지만 설명은 안할 것.
- 3 - 서버 프로그램이 사용할 IP Add
- 4 - Port num
- 7 - Socket_STREAM : TCP를 쓰겠다
with = as 앞의 내용을 수행하고 serverSocket에 의미있는 정보가 들어가면 아래를 수행- 8 - 본인의 정보로 socket 열고 준비됨!
- 9 - 기다리기
- 10 - 연결요청
- 11 - with로 client가 유효한지 확인
- 13 - 정보 주고받기 / 받은거 다시 CLIENT에게 보냄 (Echo)
- 18 - client가 quit보내면 중단
3,4 - Server의 주소
11 - 타이핑 요청
12 - 서버에게 보내기
13 - 다시 Client에게 보내면 recv로 받아서 화면에 출력
Socket( )
TCP는 stream base로 byte단위로 전송 / UDP : user datagram방식
SOCK_RAW : network layer위에서 쓰는 것 / 원래 소켓은 4계층위에서 짜는데. 극단적으로 TCP UDP를 쓰지 않고 알아서 하겠다~ 할 때 쓰는 것.
bind( )
listen( )
0이오면 request 받아 연결이 만들어진 것
-1 는 실패
accept( )
이제 client쪽
connect( )
돌아가는 내용은 동일
아까와 달리 에러처리도 넣어줌
통신에서 아주 중요
우리가 할 것 (1:N)
1. Socket API 사용 X / Python이 제공하는 socket server 사용
2. Multi-thread
-> Multi threading을 이용해서 여러개의 client 요청을 동시에 받으며 각각이 독립적으로 동작하도록 할것이다.
[접근1]
[접근2] -> 우리가 이걸 사용
TCP Server만들기
- requesetHandler만들기
base requesthandler를 제공하기 때문에 이중에서 일부를 수정해서 사용
가장 많이 수정해야할 부분은 handle() method- TCP Server class를 객체로 만들기
IP Add 주기 + 1.에서만든 핸들러 클리스 주기.- handle_request 나 serve_forever 실행해서 무한루프 돌리기
p.32
서버가 실행이 되어서 main에 들어가면 단계별로 진행
하는 일도 받는걸 해야하고, 받았으면 보내야하고.. 이런식으로 또깍또깍
프로그램이 시작해서 끝날때까지 정해진 행동함.
- 동기식
- A와 B 사이에 선후관계가 명확하여 client1이 동작을 마쳐야 client2가 동작한다.
- 단점 : blocking / 응답을 받기 전까지 처리못하고 기다린다
- 비동기식
여러 client의 요청이 동시에 와도 동시에 처리 가능 / non-blocking - 안기다려용
Multi-Process
Multi-Thread
[단계 1] - socketserver의 multi-thread 버전 생성
- TCP서버와 ThreadingMixIn을 베이스로 생성
[단계 2] - Request Handler 수정
- threading.current_thread( ) / cur_threaed.name 등 추가
[단계 3] - Main Thread 설정 및 실행
- handler 뿐만 아니라 main도 thread화 된다. 각각 모두 독립적으로 작동.
- quit할 때 두가지 방법
- main부가 더이상 thread가 필요없다고 판단하면 main이 죽을 때 thread도 함께 죽인다.(daemon_thread = True)
- main이 죽어도 thread는 살아있는 방법도 있음(daemon_thread = False)
if baseThreadNum == active_count()
-> 뒤에서 작없하는 handler thread가 다 죽었다는 뜻 = 종료
- Server 변경
- 모든 client의 socket 연결 정보를 저장
- Client와 연결 등록 & 해지
- 특정 client가 메세지를 보내면 전체 client에게 복사해서 전달
- TCP 서버는 connection oriented -> connection 정보 = client 정보
- Client 변경
- 전송은 Thread화 X / 수신은 Thread화
- Client가 타이핑을 하면서 동시에 수신 가능하도록 (비동기식) = 서버가 echo를 하든말든 타이핑 가능
- main은 키보드에서 입력받아서 server로 보내는 걸 계속하고 수신프로그램(multi thread)은 기다리고 있다가 server에서 뭐가 올때마다 화면에 뿌리기.