Python의 소켓 프로그래밍 (UDP 편)

11069 단어 socketPython3
플러그인 프로그램이 설계한 UDP 통신의 개요에 따라 파이톤으로 기본 절차를 실현하고 싶습니다.
※ [2010/11] 본고는 소스 코드의 실행 결과를 담은 기사를 업데이트했습니다.
Python의 소켓 프로그래밍 (UDP 편)

주의 사항


우선 주의사항은 인터넷 프로그램 사용 방법에 따라 DOS 공격처럼 타인의 네트워크에 영향을 미칠 수 있다는 점이다.
다른 사람의 네트워크에 곤란을 초래하는 통신을 하지 않도록 주의하세요.
본 보도의 내용에 초래된 어떠한 손실에 대해서도 필자는 책임을 질 수 없다.

UDP 기반 소켓 프로그래밍


소켓은 응용 프로그램에서 네트워크 통신 서비스를 받을 때의 API입니다.
UDP의 소켓 통신의 예를 시퀀스 맵으로 보여 줍니다.
서버는 커뮤니케이션을 수락하고 Client에서 받은 커뮤니케이션에 응답합니다.

서버 측 처리

  • socket 시스템 호출을 사용하여 UDP용 소켓을 생성합니다.
  • bind 시스템 호출을 사용하는 IP 주소와 포트 번호를 지정합니다.
    이로써 OS 내에서 그룹을 수신할 준비가 되었습니다.
  • Recvfrom 시스템 호출을 사용하여 클라이언트 메시지를 기다립니다.
    서버 프로그램은 recvfrom의 매개 변수에서 받은 메시지의 발송자(Client)의 IP 주소와 포트 번호를 파악한다.
  • sendto 시스템 호출을 사용하여 Center에 메시지를 보냅니다.
    서버가 메시지를 보낼 때 recvfrom 시스템 호출을 사용하여 받은 IP와 포트입니다.
  • 클라이언트 측 처리

  • socket 시스템 호출을 사용하여 UDP용 소켓을 생성합니다.
  • sendto 시스템 호출을 사용하여 서버에 메시지를 보냅니다.
    Client 측 포트 번호는 처음에 sendto를 실행할 때 OS에서 자동으로 할당됩니다.
  • recvfrom 시스템 호출을 통해 서버로부터 메시지를 받습니다.
  • 소켓 시스템 호출


    이번 보도에 사용된 플러그인 시스템 호출을 기록합니다.
    TCP와 같은 연결형 통신을 할 때 다른 필요한 시스템 호출도 증가한다.
    시스템 호출
    설명
    socket()
    소켓을 작성합니다.
    bind()
    소켓에 호스트의 IP 주소(포트 번호)를 설정합니다.
    recvfrom()
    메시지의 수신을 수락합니다. (연결형이 없습니다.)보내는 사람의 주소를 반환값으로 가져옵니다.
    sendto()
    목적지를 보내는 주소를 지정합니다. 메시지 보내기 (연결형 없음).
    close()
    소켓을 닫습니다.
    다음은 psyhon이 상기 절차를 실현하는 원본 코드입니다.

    소스 코드


    client.py
    import socket
    
    M_SIZE = 1024
    
    # Serverのアドレスを用意。Serverのアドレスは確認しておく必要がある。
    serv_address = ('127.0.0.1', 8890)
    
    # ①ソケットを作成する
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    
    while True:
        try:
            # ②messageを送信する
            print('Input any messages, Type [end] to exit')
            message = input()
            if message != 'end':
                send_len = sock.sendto(message.encode('utf-8'), serv_address)
                # ※sendtoメソッドはkeyword arguments(address=serv_addressのような形式)を受け付けないので注意
    
                # ③Serverからのmessageを受付開始
                print('Waiting response from Server')
                rx_meesage, addr = sock.recvfrom(M_SIZE)
                print(f"[Server]: {rx_meesage.decode(encoding='utf-8')}")
    
            else:
                print('closing socket')
                sock.close()
                print('done')
                break
    
        except KeyboardInterrupt:
            print('closing socket')
            sock.close()
            print('done')
            break
    
    
    server.py
    import socket
    import time
    
    M_SIZE = 1024
    
    # 
    host = '127.0.0.1'
    port = 8890
    
    locaddr = (host, port)
    
    # ①ソケットを作成する
    sock = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)
    print('create socket')
    
    # ②自ホストで使用するIPアドレスとポート番号を指定
    sock.bind(locaddr)
    
    while True:
        try :
            # ③Clientからのmessageの受付開始
            print('Waiting message')
            message, cli_addr = sock.recvfrom(M_SIZE)
            message = message.decode(encoding='utf-8')
            print(f'Received message is [{message}]')
    
            # Clientが受信待ちになるまで待つため
            time.sleep(1)
    
            # ④Clientへ受信完了messageを送信
            print('Send response to Client')
            sock.sendto('Success to receive message'.encode(encoding='utf-8'), cli_addr)
    
        except KeyboardInterrupt:
            print ('\n . . .\n')
            sock.close()
            break
    

    끝맺다


    Python에 대한 UDP 통신이 종료되었습니다.
    필요하면 나도 TCP 편을 쓰고 싶다.

    참고 자료

  • [1] TCP/IP 네트워크 실험 프로그래밍 지원 Linux/FreeBSD
  • [2] 로우 레벨 네트워크 인터페이스
  • 문외한, 문장의 서열도는 StackEdit 를 이용하여 Mardown에 기재된 서열도를 캡처하고 붙이는 것이다.
    그때 마크 다운도 미리 붙였을 거라고 생각해요.
    sequenceDiagram
    participant Client
    participant Server
    Note over Server: ① socket
    Note right of Server: UDP用のSocketを<br/>作成 
    Note over Client: ① socket
    Note left of Client: UDP用のSocketを<br/>作成 
    Note over Server: ② bind
    Note right of Server: ServerのIP、Portを<br/>設定 
    Note over Server: ③ recvfrom
    Note right of Server: Clientからの受信<br/>待ち
    Note over Client: ② sendto
    Note left of Client: Serverへmessageを<br/>送信
    Client ->> Server: message
    Note over Client: ③ recvfrom
    Note left of Client: Serverからの<br/>受信待ち
    Note over Server: ④ sendto
    Note right of Server: Serverへmessageを<br/>送信
    Server ->> Client: message
    

    좋은 웹페이지 즐겨찾기