10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Python3] UDP でデータを送受信する方法

Last updated at Posted at 2019-11-06

環境

python 3.x
OS は問わない

送信側

udpsend.py
from socket import *

## UDP送信クラス
class udpsend():
    def __init__(self):

        SrcIP = "127.0.0.1"                             # 送信元IP
        SrcPort = 11111                                 # 送信元ポート番号
        self.SrcAddr = (SrcIP,SrcPort)                  # アドレスをtupleに格納

        DstIP = "127.0.0.1"                             # 宛先IP
        DstPort = 22222                                 # 宛先ポート番号
        self.DstAddr = (DstIP,DstPort)                  # アドレスをtupleに格納

        self.udpClntSock = socket(AF_INET, SOCK_DGRAM)  # ソケット作成
        self.udpClntSock.bind(self.SrcAddr)             # 送信元アドレスでバインド

    def send(self):

        data = "Hello"
        data = data.encode('utf-8')                     # バイナリに変換

        self.udpClntSock.sendto(data, self.DstAddr)     # 宛先アドレスに送信

udp = udpsend()     # クラス呼び出し
udp.send()          # 関数実行
  • socket の引数の AF_INET は IPv4 用。AF_INET6 は IPv6 用
  • SOCK_DGRAM は UDP 用。TCP の場合は SOCK_STREAM
  • DstAddr でバインドしなくてもデータを送信できるが、バインドしないと送信元アドレスが固定されない
    • 受信側で送信元を指定する場合は設定しておいたほうが吉
  • sendto するときにデータをバイナリに変換する必要がある
  • "127.0.0.1" は自分自身のIPアドレスなので、任意に変更すると異なる機器間で通信が可能

受信側

udprecv.py
from socket import *

## UDP受信クラス
class udprecv():
    def __init__(self):

        SrcIP = "127.0.0.1"                             # 受信元IP
        SrcPort = 22222                                 # 受信元ポート番号
        self.SrcAddr = (SrcIP, SrcPort)                 # アドレスをtupleに格納

        self.BUFSIZE = 1024                             # バッファサイズ指定
        self.udpServSock = socket(AF_INET, SOCK_DGRAM)  # ソケット作成
        self.udpServSock.bind(self.SrcAddr)             # 受信元アドレスでバインド

    def recv(self):
        while True:                                     # 常に受信待ち

            data, addr = self.udpServSock.recvfrom(self.BUFSIZE)
                                                        # 受信
            print(data.decode(), addr)                  # 受信データと送信アドレス表示

udp = udprecv()     # クラス呼び出し
udp.recv()          # 関数実行
  • 受信側では受信するアドレスでバインドして受信を待つ
    • 送信アドレスを指定したりせず全てを受け入れる
  • print で送信したデータと送信元のアドレスを表示する
  • バッファサイズはデータサイズによって変更してほしい

実行方法

コンソールを2つ起動。
cd ~~ で .pyファイルがある場所へディレクトリ移動。

受信側(コンソール①)

python3 udprecv.py

これで受信待ち状態になる。

送信側(コンソール②)

python3 udpsend.py

"Hello" を1回送信する。

実行結果(コンソール①)

Hello ('127.0.0.1', 11111)

まとめ

通信プロトコルの一つであるUDPでデータを送受信することができた。
個人的にひっかかったのは、アドレスをバインドする意味が始め分からなかったところである。
送信側で送信先を指定しないと、、と思って送信先アドレスでバインドするとうまくいかなかった。
要するに、間違っていたのは
「ソケットをバインドする」=「自らのアドレスで固定する」
というところだった。

新卒、勉強不足。

解釈に間違いがあれば指摘してほしい。

10
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?