네트워크 소켓으로 통신하기
[네트워크] 소켓으로 통신하기
- 스트림을 생성하여 소켓으로 통신할 수 있다.
* 소켓 : 원격 사용자와 통신을 하기 위한 객체
1) 클라이언트 소켓 : 연결을 요청
2) 서버 소켓 : 요청된 연결을 받음
네트워크에서는 프로토콜에 따른 소켓을 사용하여 다른 사용자와 통신을 할 수 있습니다.
프로토콜이란, 일종의 통신규악이라고 볼 수 있습니다. 대표적으로 TCP/IP가 있죠.
오늘 포스팅 할 내용은 서버와 클라이언트단에서 이루어지는 소켓통신에 대해 포스팅을 해보도록 하겠습니다.
소켓 통신을 파이썬 프로그래밍 언어를 사용해서 진행할 것이기 때문에 좀 더 자세한 내용은
python 공식 홈페이지에서 확인하시면 됩니다. <소켓 프로그래밍 링크>
[1단계. 소켓 연결하기] - 서버(Server)
* 필요한 소켓
- 서버 소켓
- 연결요청을 한 클라이언트 소켓
* 단계
1) 소켓 생성
2) bind (포트 오픈)
* 포트 : 운영체제상에서 서비스를 식별할 수 있는 번호
* LISTEN : 연결을 받을 준비가 되어 있음
* 포트 번호가 겹치면 안 됨
3) Listen (연결을 기다림)
- 클라이언트가 나에게 연결이 올 때까지 기다림
- 연결이 올 때까지 아래쪽 코드는 실행되지 않는다.(블럭)
4) accept (요청 수락)
1~2) 소켓 생성, bind
>>> import socket
>>> server_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> server_sock.bind(('', 22222))
먼저 파이썬에서 소켓을 사용하려면 소켓 모듈을 가져와야 합니다.
위와 같이 socket을 import 해 준후 server_sock 이라는 이름으로 소켓을 생성해 줍니다.
여기서 소켓을 생성할 때는 다음과 같은 형식으로 작성해 주면 됩니다.
>>> socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
- family : AF_INET (default), AF_INET6, AF_UNIX, AF_CAN
* AF_INET : IPv4
* AF_INET6 : IPv6
* AF_UNIX 는 linux 와 unix에서만 사용할 수 있습니다.
* AF_CAN : 물리적인 통신을 할 때 사용
- type : SOCK_STREAM (default), SOCK_DGRAM, SOCK_RAW
* SOCK_STREAM : TCP
* SOCK_DGRAM : UDP
family 와 type는 각각 프로토콜, 통신방법이라고 보시면 됩니다.
위에서는 socket 모듈을 import 해온것이므로 socket 앞에 socket. 을 꼭 붙여주셔야 합니다.
저는 IPv4의 TCP 통신으로 소켓을 생성한 후 22222번 포트를 오픈했습니다.
3) Listen
>>> server_sock.listen(1)
listen을 입력하면 연결을 받을 준비가 됩니다. 여기서 괄호안에 숫자는 열어 놓은 포트 안에서 받을 수 있는 클라이언트 숫자라고 보면 됩니다.
위의 사진처럼 listen 상태면 ss -ant 명령어로 22222번 포트가 열려 있는 모습을 볼 수 있습니다.
4)accept (요청 수락)
>>> server_sock.accept()
다른 사용자로부터의 연결 요청을 수락한 상태입니다. 이제 클라이언트의 연결요청을 기다리는 일만 남았습니다.
[1단계. 소켓 연결하기] - 클라이언트(Client)
* 필요한 소켓
- 서버에 연결요청을 할 클라이언트 소켓
* 단계
1) 소켓 생성
2) 소켓 연결
1) 소켓 생성
>>> import socket
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
서버에서 생성한 소켓과 마찬가지로 소켓 모듈을 import 한 뒤에 소켓을 생성해줍니다.
※ 이때 반드시 소켓 속성은 연결할 서버와 똑같아야 합니다. 안그러면 통신이 되지 않습니다...
2) 소켓 연결
>>> sock.connect(('연결한 서버 IP 주소', 22222))
클라이언트단에서는 아주 간단합니다. 소켓을 서버 통신 속성에 맞게 생성한 후 열린 포트로 연결만 하면 됩니다.
그러면 서버쪽에서는 위와같이 서버에 연결한 클라이언트에 대한 정보가 뜹니다.
(<socket.socket fd=5, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM,
proto=0, laddr=('서버 IP', 22222), raddr=('클라이언트 IP', 46932)>,
- 클라이언트 소켓
('클라이언트 IP', 46932))
- 연결한 클라이언트의 IP와 클라이언트의 포트
[2단계. 소켓으로 입출력하기] - 서버(Server)
>>> client_sock, info = server_sock.accept()
이번에는 소켓으로 입출력하기 위해서 server_sock에 저장된 속성을 사용하여 새로운
client_sock, info라는이름을 만들고 클라이언트의 연결을 기다립니다.
[2단계. 소켓으로 입출력하기] - 클라이언트(Client)
1) 소켓 생성 및 연결
>>> import socket
>>> sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> sock.connect(('192.168.3.108', 22222))
파일 입출력을 위해 새로 소켓을 다시 연결해 봅니다. 1단계와 똑같이 연결하시면 됩니다.
2) 메시지 입력
>>> sock.send(b'hello')
이제 소켓에 메세지를 입력해 봅니다. 메세지 앞에 b가 뭐냐하면 바로 byte 인데, 파이썬3에서는 그냥 메세지를 전달하면 str 형식은 지원하지 않는다는 에러가 발생합니다. 그래서 이를 byte 형식으로 변환하기 위해 b를 붙입니다. 밑에 5는 5byte를 보냈다는 뜻이겠죠.
[2단계] - 서버(Server)
1) 연결 정보 확인
다시 서버로 돌아와서 클라이언트가 연결을 하면 위와 같은 정보를 확인하실 수 있습니다.
각각 소켓 정보, 클라이언트 정보로 보시면 되겠네요.
2) 메시지 출력
>>> client_sock.recv(1500)
전에 클라이언트쪽에서 메세지를 입력했으니 서버에서는 출력이 필요하겠죠.
recv 함수를 이용해서 입력한 메세지를 출력할 수 있습니다. 1500은 최대 받을 수 있는 byte 수 입니다.
영문자, 숫자는 1자당 1byte, 한글은 2byte를 사용합니다.
이를 활용하면 소켓 프로그래밍등 파일로 만들어서 사용할 수도 있습니다.
그것에 대해서는 다음 포스팅에서 다루도록 하겠습니다~
'Security > network' 카테고리의 다른 글
IP 주소체계와 클래스 구성 (0) | 2017.03.29 |
---|---|
TCP 3 way-handshake(SYN, ACK) (0) | 2017.03.29 |
TCP / UDP 의 특징 및 헤더(header) 분석 (0) | 2017.03.29 |
VMware 네트워크 설정 (0) | 2016.11.07 |
IP/서브넷 마스크 (0) | 2016.11.01 |