티스토리 뷰

Python

네트워크

˙ᵕ˙ 2020. 8. 29. 01:18

파이썬의 네트워크

TCP/IP 프로토콜

  • 응용 계층은 TCP/IP 프로토콜을 이용하는 응용 서비스로서 TCP 또는 UDP가 지원하는 응용으로 각각 구분할 수 있다.

  • 소켓(socket)은 응용프로그램에서 TCP/IP를 이용하는 창구 역할을 하며 응용 프로그램과 소켓 사이의 인터페이스를 소켓 인터페이스 라고 한다.

  • TCP : 신뢰성, 재전송에 의한 오류제어 흐름제어를 하는 스트림 형태의 연결형 서비스

  • UDP : 오류제어와 흐름제어가 없는 비연결형 서비스

  • 트랜스포트 계층은 호스트 사이의 종점간 연결을 제공하고 종점간의 데이터 전달을 처리

  • 인터넷 계층은 비 연결형 서비스, 데이터그램 방식으로 호스트 사이에 IP패킷을 전달하는 기능과 라우팅 등을 수행

파이썬의 TCP 소켓 모듈

  • 소켓 모듈의 주요 메소드

메소드 설명
bind() 소켓에 주소를 바인드 한다.
listen() TCP listener 설정하고 시작한다.
accept() TCP 클라이언트 연결을 수동적으로 받아들이고 연결이 도착할 때까지 기다린다.
connect() TCP 서버연결을 능동적으로 초기화한다.
recv() TCP 메시지를 수신한다.
end() TCP 메시지를 전송한다.
recvfrom() UDP 메시지를 수신한다.
sendto() UDP 메시지를 전송한다.
close() 소켓을 종료
더보기

AF_UNIX : 두 프로세서가 같은 기계에서 실행. 파일기반 소켓
AF_INET : 한 머신에서의 프로세서가 다른 머신에 있는 프로세서와 대화하는 네트워크 소켓

  • socket 연결방법

  • connection-oriented 형

    • 쌍방이 연결되어 있는 상태로 소통

    • 데이터 손상이 적다 (안정적)

    • 데이터는 작은 조각으로 분해 된 후 순서대로 보내고 상대방에 도착한 후, 순서대로 읽어 들인다.

    • 이 방식으로 연결하는 socket 유형을 SOCK_STREAM 이라고 한다.

    • TCP

  • connectionless 형

    • 소통없이 일괄로 통신을 전달

    • 발송지 확인을 취하지 않고 데이터 전송하며 수신된 데이터에만 반응

    • 데이터는 datagram을 한 묶음의 형태로 전달

    • 신뢰성이 낮지만 부하가 가볍다.

    • 이 방식으로 연결하는 socket 유형을 SOCK_DGRAM 이라고 한다.

    • UDP

파이썬의 TCP 통신

< SimpleServer.py >

import socket   # 소켓 모듈 임포트

HOST = '127.0.0.1'  # 로컬 호스트
PORT = 55555    # 포트 지정

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 소켓 생성
print('서버를 실행합니다.')

s.bind((HOST, PORT))    # 주소와 소켓 결합
s.listen(1)     # 연결 요청을 하나의 요청만 받기 위해 1

conn, addr = s.accept()     # 연결요청 수락하고 연결 소켓 생성
print('Connected by', addr)
while 1:
    data = conn.recv(1024)  # 클라이언트에서 데이터 수신
    if not data:
        break
    conn.send(data + b':from server')    # 클라이언트로 데이터 송신
conn.close()       # 서버 종료

< SimpleClient.py >

import socket   # 소켓모듈 임포트

HOST = '127.0.0.1'  # 서버에 접속할 주소 지정
PORT = 55555    # 서버에 접속할 포트 지정

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   # 소켓 생성
s.connect((HOST, PORT)) # 서버에 연결. 이때 서버는 accept()메소드 호출
s.send('Hello World'.encode(encoding='utf_8', errors='strict')) # 서버로 데이터 송신
data = s.recv(1024) # 서버로부터 데이터 수신
s.close()   # 소켓 종료
print(data)

  • 서버에 여러 클라이언트 접속

< TcpServer.py >

import socket
import threading

bind_ip = '127.0.0.1'
bind_port = 9999

# socket.AF_INET에서 ip4를 사용하는 것을 지정.
# socket.SOCK_STREAM에서 TCP를 사용하는 것을 지정.
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 자신의 IP주소와 port를 설정한다.
# 상대방의 IP주소와 port를 설정하는 경우 connect를 사용한다고 생각 할 수 있다.
server.bind((bind_ip, bind_port))

# 연결의 최대 저장 수 설정
server.listen(5)

print(f'[*] Listening on {bind_ip} : {bind_port}')

def handle_client(client_socket):
    bufsize = 1024
    request = client_socket.recv(bufsize)
    print(f'[*] Recieved {request}')
    client_socket.send('Hello Client!!!')
    client_socket.close()

while True:
    # bind 된 소켓에서 새로운 소켓과 연결된 주소를 반환
    client, addr = server.accept()

    print(f'[*] Accepted connection from : {addr[0]} : {addr[1]}')

    # threading을 사용하여 스레드를 생성
    # 멀티코어에 대응시키고 시은 경우는 multiprocessing을 사용
    # target은 호출 함수 (객체)를 지정하고 args는 그 인수를 지정 
    client_handler = threading.Thread(target=handle_client, args=(client,))
    client_handler.start()

< TcpClient.py >

import socket

target_url = '127.0.0.1'
target_port = 9999

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target_url, target_port))

s.send('Hello Server!!!'.encode(encoding='utf_8', errors='strict'))
response = s.recv(4096)
print(response)

UDP통신

  • TCP서버와 차이는 listen 메소드를 사용하지 않는다.

  • socket 생성시 SOCK_DGRAM을 이용한다

< UDPServer.py >

from socket import *
from time import ctime

HOST = '127.0.0.1'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpSerSock = socket(AF_INET, SOCK_DGRAM)
udpSerSock.bind(ADDR)

while True:
    print('waiting for message...')
    data, addr = udpSerSock.recvfrom(BUFSIZ)

    udpSerSock.sendto(str(data).encode('utf_8', 'strict'), addr)
    print(f'... received from and return to : {addr}')

udpSerSock.close()

< UDPClient.py >

from socket import *

HOST = '127.0.0.1'
PORT = 21567
BUFSIZ = 1024
ADDR = (HOST, PORT)

udpCliSock = socket(AF_INET, SOCK_DGRAM)

while True:
    data = input( '>')
    if not data:
        break
    udpCliSock.sendto(str(data).encode(encoding='utf_8', errors='strict'), ADDR)
    data, ADDR = udpCliSock.recvfrom(BUFSIZ)
    if not data:
        break
    print(data)

udpCliSock.close()

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함