OSI 7 Layer 중에 4계층인 전송 계층에 대해 알아보겠다.
TCP : 전송 제어 프로토콜(Transmission Control Protocol)
그럼 Protocol 이란 무엇인가?
한마디로 원활한 네트워크 통신(데이터를 주고 받기 위한)을 위한 약속이라고 할 수 있다.
프로토콜 중 수 많은 종류들이 있는데 그중 일반적으로 제일 많이 쓰고 우리가 알아야할것이 바로 TCP이다.
소켓
- 파일을 읽기 위해 파일객체를 만드는것 처럼 네트워크 통신을 하려면 소켓을 만들어야한다.( FD의 연장선에서 이해)
- 원격에 있는 상대방과 통신하기 위해 객체가 필요한데 그것을 '소켓' 이라고 부른다.
- Socket Object
- 종류(Client Socket / Server Socket)
1. TCP Client Socket
import socket // 소켓 모듈을 import 한다.
client_sock = socket.socket( socket.AF_INET , socket.SOCK_STREAM ) // 소켓(객체)를 만들어준다.
함수 원형 socket.socket( family, type, proto = 0) 리턴값 : socket 객체
- family : 주소체계(Address Family) 표시, 인터넷인 경우 AF_INET ( IPv4 )
- type : 인터넷인 경우 트랜스포트 서비스 표시
TCP = SOCK_STREAM
-연결 지향형 소켓, 데이터 손실 없이 목적지로 전송, 전송 순서대로 데이터가 수신됨, 데이터 경계 없음
UDP = SOCK_DGRAM
- 비 연결 지향형 소켓, 데이터 손실 우려가 있음, 전송된 순서에 상관없이 가장 빠른 전송 지향, 데이터 경계 존재
HOST = '192.168.11.166' // 연결할 서버의 IP
PORT = 20000 // 연결할 서버의 포트
well-known port : 1 ~ ( 1024~10000 ) ex) ssh port = 22 , http port = 80
client_sock.connect( (HOST , PORT) ) // 생성된 소켓 객체를 통해 누구랑 연결할지를 결정
data = input( 'any input : ') // 서버에게 전송할 데이터를 변수에 대입
client_sock.send( data.encode() ) // 데이터를 보낸다.
deta.encode() : 파이썬의 str 타입은 유니코드이므로 아스키코드로 바이트(bytes)화해서 데이터를 전송해야한다.
data = client_sock.recv( 65535 ) // 서버에서 보낸 데이터를 받는다.
인자값에는 한 번에 받을 수 있는 데이터의 최대 바이트 수
print( 'echo : ' + data.decode() ) // 받은 데이터를 출력한다.
2. TCP Server Socket
import socket
server_socket = socket.socket( socket.AF_INET , socket.SOCK_STREAM ) // 소켓 객체를 만들어준다.
server_socket.bind( ('' , 20000) ) // 생성된 소켓 객체를 통해 사용할 호스트와 포트를 정한다.
.bind( address ) - address(튜플) : ( HOST , PORT )
- 어떤 HOST(상대방)로부터 몇번 PORT(자신의포트)를 통해 연결을 받겠다.
server_socket.listen(1) // 클라이언트의 연결을 받기위해 대기상태로 전환한다.
.listen( ) : 생성된 소켓 객체를 통해 연결할 수 있는 최대 갯수를 인자값에 넣는다.
client_sock , address = server_socket.accept() // 클라이언트 연결 요청이 오면 해당 클라이언트에 대한
.accept() return ( socket , address) 소켓 객체를 생성해서 변수에 대입한다.
- client가 연결을 요청하면 server에서 수락하는 함수
- 수락과 동시에 또하나의 소켓이 생성된다. listen으로 설정된 소켓은 또 다른 client의 연결을 받기위해 계속 대기 해야 하기 때문이다.
print( 'IP : ' + address[0] + ' PORT : ' + address[1] ) // 클라이언트의 주소와 포트를 출력한다.
address(튜플) = ( HOST , PORT )
data = client_sock.recv( 65535 ) // 클라이언트에게 데이터를 받는다.
print( 'recv : ' + data.decode() ) // 바이트(bytes)화된 데이터를 디코딩해서 출력한다.
client_sock.send( data ) // 수신된 데이터를 돌려준다.
client_sock.close()
server_socket.close()
<서버> <클라이언트>
'Hacking > Network' 카테고리의 다른 글
[5일차] UDP 헤더 패킷 분석하기 (0) | 2017.09.19 |
---|---|
Raw 소켓 프로그래밍 (0) | 2017.09.15 |
[4일차] 파이썬을 이용한 UDP 소켓 프로그래밍 (0) | 2017.09.14 |
파이썬 설치 (0) | 2017.09.11 |
환경 구축 (0) | 2017.09.11 |
WRITTEN BY