Shell Script 문법 정리
Title: Bash Shell Script 문법 정리 Author: DongDongE Tags: Programming Release: 2021.02.08 [Shell
요새 Python Flask와 Docker을 공부하고 있어서 블로그에 정리를 해보려고 합니다.
띠용!!
본글은 Linux Ubuntu 환경의 Python 2.7 기반으로 진행합니다.
Description: Ubuntu 19.04
Release: 19.04
Codename : Disco Dingo
Network Socket Address에는 IP Address와 Port Number을 포함한다.
Socket을 생성하기 위해 Python의 socket 모듈의 socket.socket() 함수를 사용해야 한다. 아래 예시 하나를 보자!!
soc = socket(socket_family, socket_type, protocol = 0)
socket_family = socket.AF_INET, PF_PACKET
socket_type = socket.SOCK_DGRAM, socket_SOCK_STREAM
socket.bind(Address)
socket.listen(q)
socket.accept()
socket.connect(Server Address)
1. 클라이언트에서 서버로 연결하는 메소드이다.socket.recv(buf_size)
socket.recvfrom(buf_size)
socket.recv_into(buf)
socket.recvfrom_into(buf)
socket.send(bytes)
socket.sendto(data, address)
socket.sendall(data)
import socket
host = "192.168.219.133" # Server IP
port = 1234 # Port Number
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # TCP 소켓 생성
soc.bind((host, port)) # host와 port로 소켓 연결
soc.listen(5) # 클라이언트 최대 5개 까지 받으며 접속할 때 까지 대기
conn, addr = soc.accept() # 연결 허용, conn 변수에는 클라이언트 소켓이 저장되고, addr에는 클라이언트 아이피 주소가 저장된다.
print addr # 클라이언트 IP 주소 출력
conn.send("Hi!! Server is DongDongE") # 클라이언트에 문자열 전송
conn.close() # 소켓 종료
import socket
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = "192.168.219.133" # 서버 아이피
port = 1234 # 서버 포트
soc.connect( (host, port) ) # 서버측으로 연결한다.
print soc.recv(1024) # 서버측에서 보낸 데이터 1024 버퍼만큼 받는다.
soc.send("Client. Hello!!!") # 서버측으로 문자열을 보낸다.
soc.close() # 연결 종료
서버측에서 sev.py을 실행시키면 클라이언트가 접속하기전 까지 터미널창에는 아무런 반응이 보이지 않는다. 하지만 아래 사진과 같이 프로세스를 확인해보면 정상적으로 port가 열린걸 볼 수 있다.
Client측에서 실행한다면 서버에 연결하고나서 서버측에서 보낸 문자열을 받는다.
서버측에서 클라이언트의 IP주소와 클라이언트 포트번호를 확인할 수 있다.
해당 코드는 서버측으로 연결을 하면 계속 유지하지 않고 연결을 바로 끊어 버린다. 만약 다른 클라이언트(유저)를 받기 위해서 서버측 소켓을 계속 활성화 (while 반복문 사용)을 시켜줘야 한다.
캡처된 패킷을 Wireshark을 통해 Server와 Client간 패킷을 볼 수 있다.
먼저 TCP 3-way handshake 과정을 거친 다음 PSH,ACK로 데이터를 보내는걸 볼 수 있다.
아래 사진에서 전송된 데이터를 확인 해보자.
Data부분을 보면 Server가 Client로 "Hi! is..." 문자열을 전송하는걸 볼 수 있다. 전송시 평문으로 전송하기 때문에 Wireshark로 패킷을 캡처하여 문자열을 볼 수 있다.
import socket
host = "192.168.219.133"
port = 1234
soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
soc.bind((host, port))
soc.listen(5)
while(True):
conn, addr = soc.accept()
print addr
conn.send("Hi!! Server is DongDongE")
conn.close()
위의 코드중 while문을 통해서 하나의 서버에서 여러대의 클라리언트 요청을 계속 처리 및 제공할 수 있다.
While 구문을 통해 다수의 연결접속에도 서버가 종료되지 않고 계속 작동되는걸 볼 수 있다.
아래는 클라이언트가 연속적으로 연결 접속을 시도한 사진이다.
import socket
host = "192.168.219.133"
port = 4321
soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
soc.bind((host, port))
data, addr = soc.recvfrom(1024)
print "IP: ", addr
print "Data: ", data
soc.close()
UDP는 비연결형 프로토콜이므로, 연결 설정 (3 way handshake)과정이 필요 없다.
import socket
host = "192.168.219.133"
port = 4321
soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
print soc.sendto("Hello All", (host, port))
soc.close()
TCP와 다르게 Connect후 전송하는 과정 없이 바로 sendto 메소드에 전송할 문자열과 Server IP, PORT을 적어 전송한다.
위 사진을 보면 연결 과정 없이 Client가 Server로 바로 데이터를 전송한다.
하지만 초록색 박스를 보면 "192.168.219.134" 클라이언트가 서버로 "192.168.219.133" 데이터를 전송했지만 서버측에서 "ICMP Destination unreachable" 패킷이 반환된 걸 확인할 수 있다.
이 패킷은 해당 프로세스에서 정상적으로 열려 있지 않거나 방화벽으로 인해 정상적인 처리를 할 수 없을 때 반환되는 패킷이다. (TCP 경우 RST 패킷을 반환한다.)
아래 사진에서는 전송된 데이터를 확인 해보자.
UDP Packet의 Data 부분에 "Hello All" 문자열을 담아 전송된걸 확인 할 수 있다.