質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Q&A

解決済

1回答

1968閲覧

Go言語で発信に対する応答が受信できない(UDP通信)

kamuycikap

総合スコア135

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

UDP

UDP(User Datagram Protocol)とは、トランスポート層のプロトコルであり、コネクション型のデータサービスです。IPネットワーク上の別のホストにコンピュータのアプリケーションがメッセージを送ることができ、転送チャンネルやデータ経路を設定する必要はありません。TCPに比べて高速であるが、信頼性が薄いという特徴があります。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

0グッド

0クリップ

投稿2021/12/03 06:41

編集2021/12/03 06:49

Go言語によるUDP通信プログラム(クライアント)を作成しています。
参考にしたのはこちらのサイトのコード
GolangでUDPサーバー&クライアントを作成してWiresharkで検証する

問題点は、サーバーに対し、リクエストデータを発信したのち、応答を待っても受信できない事

です。
通信内容確認は、WireSharkにて行っています。
WireSharkの画面上では、サーバーに対するリクエストデータは、想定通り任意のアスキーコードを送信できており、UDPサーバーからはOK/NGのアスキー文字が応答データとして返信されています。

しかし、Goコードにて受信ができておりません。
WireShark上で閲覧できていると言う事は、UDPサーバーから応答データは発信されていると考えています。
よって、受信コードに何かしらの不備があるのではと考えているのですが、何に問題があるのかわからない状況です。

go

1 fmt.Println("UDP ResolveUDPAddr:192.168.1.201:50000") 2 udpAddr, err := net.ResolveUDPAddr("udp", "192.168.1.201:50000") // データ送り付け先 3 if err != nil { 4 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 5 os.Exit(1) 6 } 7 8 fmt.Println("UDP Dial") 9 conn, err := net.DialUDP("udp", nil, udpAddr) 10 if err != nil { 11 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 12 os.Exit(1) 13 } 14 15 fmt.Println("UDP SendCommand:STOP") 16 _, err = conn.Write([]byte("STOP\r\n")) // 停止要求コマンド 17 18 if err != nil { 19 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 20 os.Exit(1) 21 } 22 23 fmt.Println("Receiving from server") 24 buffer := make([]byte, 64) 25 length, err := conn.Read(buffer) // <-- ここで受信したいが待っている様子。 26 if err != nil { 27 panic(err) 28 } 29 fmt.Printf("Received: %s\n", string(buffer[:length])) 30

bash

1UDP ResolveUDPAddr:192.168.1.201:50000 2UDP Dial 3UDP SendCommand:STOP 4Receiving from server <-- ここで止まってしまっている。

wireshark

1■送信パケット 2\192.168.1.200:64077 -> 192.168.1.201:50000 30000 00 08 dc 54 80 9b c8 5b 76 1b f8 08 08 00 45 00 ...T...[v.....E. 40010 00 22 a0 36 00 00 80 11 00 00 c0 a8 01 c8 c0 a8 .".6............ 50020 01 c9 fa 4d c3 50 00 0e 85 01 53 54 4f 50 0d 0a ...M.P....STOP.. 6 7■受信パケット 8\192.168.1.201:50000 -> 192.168.1.200:50000 90000 c8 5b 76 1b f8 08 00 08 dc 54 80 9b 08 00 45 00 .[v......T....E. 100010 00 20 08 3c 40 00 80 11 6d af c0 a8 01 c9 c0 a8 . .<@...m....... 110020 01 c8 c3 50 c3 50 00 0c 97 fd 4f 4b 0d 0a 00 00 ...P.P....OK.... 120030 00 00 00 00 00 00 00 00 00 00 00 00 ............

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。

【結論】
UDP送信ポートと受信ポートが違うから。
WireSharkの通信結果を見ると下記の通り。
クライアント → サーバー:\192.168.1.200:64077 -> 192.168.1.201:50000
サーバー → クライアント:\192.168.1.201:50000 -> 192.168.1.200:50000

【対策】
サーバーから送り付けられる「クライアント側のUDPポート」をListenしなければならない。
元のコードでは、ポート番号64077で待ち続けいると考察。
応答は、ポート番号50000に戻ってくるため、処理が止まってしまう。

go

1package udp_client 2 3import ( 4 "fmt" 5 "net" 6 "os" 7) 8 9 10func main() { 11 12 recAddr, err := net.ListenPacket("udp", "192.168.1.200:50000") // UDP受信ポート 13 if err != nil { 14 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 15 os.Exit(1) 16 } 17 defer recAddr.Close() 18 19 fmt.Println("UDP ResolveUDPAddr:192.168.1.201:50000") 20 udpAddr, err := net.ResolveUDPAddr("udp", "192.168.1.201:50000") // データ送り付け先 21 if err != nil { 22 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 23 os.Exit(1) 24 } 25 26 fmt.Println("UDP Dial") 27 conn, err := net.DialUDP("udp", nil, udpAddr) 28 if err != nil { 29 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 30 os.Exit(1) 31 } 32 33 fmt.Println("UDP SendCommand:STOP") 34 _, err = conn.Write([]byte("STOP\r\n")) 35 if err != nil { 36 fmt.Fprintf(os.Stderr, "Fataaaaal Error ", err.Error()) 37 os.Exit(1) 38 } 39 40 fmt.Println("Receiving from server") 41 buffer := make([]byte, 64) 42 length, raddr, err := recAddr.ReadFrom(buffer) // <-- サーバー側からの受信ポートで受け取る 43 if err != nil { 44 panic(err) 45 } 46 fmt.Printf("Received: %v : %s\n", raddr, string(buffer[:length])) 47} 48

投稿2021/12/03 08:01

kamuycikap

総合スコア135

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問