네트워크란
- 떨어져 있는 Host들간의 연결 혹은 연결되어있는 집단을 말한다.
네트워크의 기원
ALPANET -> 정부, 학교, 기업들간에 서로 데이터공유를 원활하게 하고자 해서 시작된 프로젝트이다.
-> 이 때, router등 네트워크 장비들이 개발되었다.
그렇다면
네트워크에서 어떻게 데이터를 주고받을까?
-> 여러가지 프로토콜(규칙들)을 통해서 주고받는다.
네트워크에서 통신하는 모습을 오늘 확인해 볼 것이다.
네트워크의 구조부터 봐야한다.
* 네트워크 구조는 OSI 7 Layer (표준)로 이루어져있다.
크게 보면 아래와 같다.
1~4 계층
- 하위 4계층이라고 한다.
- 물리적인 전송 방법에 관해 역할을 담당한다.
- 통신규약(프로토콜)
-> TCP, UDP, IP, ARP, ETHERNET, ... (데이터를 전달하는 방법들)
5~7 계층
- 상위 3계층이라고 한다.
- 논리적인 규칙에 따라 전송된다.
- HTTP, FTP, Mail,... (프로토콜)
- kakao talk, game.. (비표준프로토콜) -> 외부에 공개되지 않는 규약들
먼저, 하위 4계층을 이용해 문자를 전송해보자.
파이썬을 이용해 1~4계층으로 메세지를 직접 주고받는 통신을 해볼 것이다.
파이썬에서 통신을 하기 위해 필요한 내용들이다.
* 파이썬 소켓 프로그래밍
-> 우리가 하려는 것이 네트워크 상에서 데이터를 주고받는 모습을 확인하려는 것이다.
그러기 위해서는 네트워크 프로그래밍을 해야한다. 네트워크 프로그래밍을 소켓 프로그래밍이라고도한다.
-> 네트워크 프로그래밍? : 통신을 위한 프로그래밍으로 소켓을 이용한다. 그래서 소켓프로그래밍이라고 하는 것이다.
- socket? 소켓을 이해하기 위해 다음것들을 먼저 보는 것이 도움이 된다.
* 입/출력 방식
- 표준 입/출력 : input(), print() (키보드, 모니터) (키보드, 모니터로 이루어지기 때문에 다른 식별자가 없다.)
- 파일 입/출력 : 파일 식별자가 필요하다. (어떤 파일을 열었는지 알아야하기 때문에 식별자가 필요하다.)
- open ( 파일을 가져온다 )
a, w, r (추가, 쓰기 읽기전용)
a -> 있으면 거기다 쓰고 없으면 새로 만든다.

(open() 을 이용해 파일입력해보는 코드)

(이렇게 바탕화면에 text 파일이 생긴다.)
핸들러 -> 파일 변수. 파일을 다룰수있는 변수

(핸들러 내용)
open 되있으면 파일이 열려있는것이다. 이 때 삭제를 누르면 열려있다고 삭제가 안된다. (열려있다는거 확인할 수 있다.)
close로 닫을 수 있다.

(Python 에서 close()를 하지 않은 경우)

(close() 를 해야 열려있던 파일이 종료된다.)
write -> 화면에는 입력한 문자의 길이가 표시된다.
* 파일을 다룰 때는 식별자를 주의해야한다.

(파일에 문자를 입력해본 결과(11이라고 적힌건 입력된 문자수를 출력한다.)
파일 접근 방법
ex) fd = open("파일 경로", "모드")
네트워크 입/출력도 파일 입/출력과 비슷하다고 생각하면 된다.
파일은 open으로 접근했다면 네트워크는 socket으로 접근한다고 생각하면 된다.
- 네트워크 입/출력 : socket (파일의 디스크립터와 같은 맥락) 소켓은 식별자이다.
ex) 서버는 여러개의 소켓꽂을 자리를 준비하고있다. 우리는 소켓을 들고가서 콕 꼽는다.
-> 네트워크 프로그래밍을 소켓프로그래밍이라고도 한다.
먼저 소켓을 생성해줘야한다. (파일입출력할때 파일을 생성한것처럼.)
1. socket 생성
- socket module
- 소켓 인자 : (1. 인터넷 타입, 2 통신 타입, 3. 프로토콜)
*인터넷 타입
- AF_INET (IPv4)
- AF_INET6
...
- AF_PACKET
* 통신 타입
- 통신하는 타입
- SOCKET_STREAM (TCP)
- SOCK_DGRAM (UDP)
- SOCK_RAW
* 프로토콜 -> defalt 값은 0이다. (안적어도 된다.)
출력해보면 볼수 있는데 fd가 중요하다. 소켓마다 번호가 다르다.
하나 더 만들면 번호가 다르게 생성된다.

(소켓 생성 모습)
* 네트워크 타입
1. 서버-클라이언트 ( 1: N )
2. Peer To Peer ( 1 : 1 ) (카톡, 채팅)
-> 알고보면 이것도 서버-클라이언트다
-> 누군가는 서버가 되야하고 클라이언트되야한다.
-> 누군가는 반드시 전화를 먼저 걸어야한다. (전화를 예로)
윈도우즈 위에 여러개의 프로그램이 있다. 그래서 포트라는 개념이 필요하다.
Port 번호를 가지고 프로그램을 식별한다.
포트 번호는 ( 1~ 65535번 ) 까지 사용한다.
1~1024번 포트는 well-known 포트번호라고 한다. 조금 공식적인 포트 번호
1~10000번 까지는 비우는게 좋다. (요새는 통신하는게 많아져서)
* IPv4, IPv6
- IP Address : 네트워크상에서 호스트를 식별할 수 있는 식별자(식별번호)
ipv4
- 4자리의 정수를 '.' 으로 구분해서 표시한다.
- 각 정수의 범위는 (0~255) 이다.
ipv6
- 6자리의 16진수 정수를 가지고 주소를 표현한다.
- 0x00 ~ 0xff (255개)
커맨드창에 아래와 같이 입력하면
netstat -anp tcp
-> 현재 열려있는 포트들을 보여준다.

(netstat -anp tcp 명령어)

(포트 번호 50000번을 열어둔 상태)

(포트번호 50000번이 열려있는 것을 확인할 수 있다.)
이제 간단한 통신을 하는 프로그램을 만들어 볼것이다.
동작 방식은
* 서버 프로그램의 동작방식
1. 소켓을 생성한다. -> socket()
2. 포트를 오픈한다. ->bind() : 튜플 형태로 하나의 인자. 튜플안에 뒤는 포트번호
3. 네트워크의 상태를 Listen 상태로 변경한다. -> listen() 괄호 안에 연결 개수를 적기도한다.
4. 클라이언트의 연결 요청을 기다린다. -> accept() : 클라이언트 소켓을 리턴해준다.
* 클라이언트 프로그램의 동작방식
1. 소켓을 생성한다. -> socket()
2. 서버에 연결한다. -> connect() : IP주소와 포트번호를 튜플형태로 적어준다.

(통신 프로그램 코드, connect()는 빠져있다.)

(서버 측 출력)
위 코드를 보면 서버 모드일 때 연결이 되면 연결되어있는 정보가 출력되는 것을 확인 할 수 있다.
리턴되는 값은 클라이언트 소켓 정보이다.
연결된 이후에는 send, recv 함수를 통해서 데이터를 송/수신 할 수 있다.
그러면 이제 메세지를 주고받겠다.

(문자열 abcde를 보내는 클라이언트 모드)

(에러가 났다.)
문자열을 그대로 보내면 파이썬은 처리를 못한다.
그래서 .encode()를 하면 파이썬이 적절하게 인코딩을 해서 보내주게 된다.

(서버에 입력이 들어온 모습)
내가 클라이언트 모드일때 abcde를 보냈고
내가 서버모드로 하고 옆사람이 클라이언트모드로 내게 Hello를 보낸 것을 확인 할 수있다.
출력 결과를보면 첫번째 꺼는
b' Hello라고 적혀있고
아래꺼는
Hello 라고 적혀있다.
첫번째꺼는 데이터 받은 것을 디코딩하지 않고 바로 출력한것이다.
보면 바이트 표시가 되있는 것을 볼 수 있다.
두번째 꺼는 .decode()를 한 모습이다.