概要
PythonとC#にて2台のPC間でUDP通信を実験し勉強したメモ。
準備
今のPCはケーブルがストレートかクロースか選ばないから、壊れてなければ、2台のPC(A,B)を接続できる。
接続したら、Local IPを設定し、PCで確認してみる。
例:A PCを192.168.0.1に、Bを192.168.0.2に設定した。
BのPCはこのような感じで設定する。
BのPC にてコマンド:ipconfig にてIP設定した結果を確認してみる
BのPC にて接続のコマンド:ping AのIP で接続を確認する。応答時間が出ていれば、これは接続できていることの証拠。
物理的な接続環境とOSレベルの接続はこれで確認完了しているから、次はBのPCでpython、AのPCでC#のUDP APIにて通信してみる。
python側
import socket
import time
M_SIZE = 1024 #bufサイズ
# 自分のPCのアドレスとport.
host = '192.168.0.2'
port = 8080
locaddr = (host, port)
# ①ソケットを作成する、simを契約したイメージ
sock = socket.socket(socket.AF_INET, type=socket.SOCK_DGRAM)
print('create socket')
# ②自ホストで使用するIPアドレスとポート番号を指定、simを携帯に挿したイメージ
sock.bind(locaddr)
while True:
try :
# ③受付待ち
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を送信
message = input()
sock.sendto(message.encode(encoding='utf-8'), cli_addr)
print('Send response to Client')
except KeyboardInterrupt:
print ('\n . . .\n')
sock.close()
break
python 側のPCは下記記事を参考にしました。
https://qiita.com/note-tech/items/c3e1e497d231ea1e7ca7
C#側
今回両方Sever設定にした。何故かよくわからないですけど、Clientにするとうまくファイアウォールをクリアできなかった。Severにすれば、bindするところでWindowsがファイアウォールをブロック解除の確認POPが出て、そこでブロックしない承認をすれば、ファイアウォールがちゃんと通信を通してくれた。UDPは実際SeverかClientか余り気にする必要がないようで、ひとまず通信できることを優先した。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace UDP_sever
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
Socket server;
private void label1_Click(object sender, EventArgs e)
{
string ip = IPAddress.Any.ToString();
textBox1.Text = ip;
}
private void button1_Click(object sender, EventArgs e)
{
server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPAddress iP = IPAddress.Parse(textBox1.Text);
IPEndPoint endPoint = new IPEndPoint(iP, int.Parse(textBox2.Text));
server.Bind(endPoint);
listBox1.Items.Add("sever setup done!");
Thread t = new Thread(ReciveMsg);
t.IsBackground = true;
t.Start();
}
void ReciveMsg()
{
while (true)
{
EndPoint point = new IPEndPoint(IPAddress.Any, 0);//用来保存发送方的ip和端口号
byte[] buffer = new byte[1024];
int length = server.ReceiveFrom(buffer, ref point);//接收数据报
string message = Encoding.UTF8.GetString(buffer, 0, length);
listBox1.Items.Add(point.ToString() + ":" + message);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (textBox3.Text != "")
{
Thread t2 = new Thread(SendMsg);
t2.Start();
}
}
void SendMsg()
{
EndPoint point = new IPEndPoint(IPAddress.Parse("192.168.0.2"), int.Parse(textBox2.Text));
string msg = textBox3.Text;
server.SendTo(Encoding.UTF8.GetBytes(msg), point);
}
}
}
namespace UDP_sever
{
partial class Form1
{
/// <summary>
/// 必要なデザイナー変数です。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
/// <param name="disposing">マネージド リソースを破棄する場合は true を指定し、その他の場合は false を指定します。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows フォーム デザイナーで生成されたコード
/// <summary>
/// デザイナー サポートに必要なメソッドです。このメソッドの内容を
/// コード エディターで変更しないでください。
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.textBox2 = new System.Windows.Forms.TextBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(299, 29);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(100, 41);
this.button1.TabIndex = 0;
this.button1.Text = "set";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(33, 29);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(59, 15);
this.label1.TabIndex = 1;
this.label1.Text = "Local IP";
this.label1.Click += new System.EventHandler(this.label1_Click);
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(110, 26);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(154, 22);
this.textBox1.TabIndex = 2;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(33, 67);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(34, 15);
this.label2.TabIndex = 1;
this.label2.Text = "Port";
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(110, 64);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(154, 22);
this.textBox2.TabIndex = 2;
this.textBox2.Text = "8080";
//
// listBox1
//
this.listBox1.FormattingEnabled = true;
this.listBox1.ItemHeight = 15;
this.listBox1.Location = new System.Drawing.Point(36, 113);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(363, 199);
this.listBox1.TabIndex = 3;
//
// textBox3
//
this.textBox3.Location = new System.Drawing.Point(36, 340);
this.textBox3.Name = "textBox3";
this.textBox3.Size = new System.Drawing.Size(255, 22);
this.textBox3.TabIndex = 2;
//
// button2
//
this.button2.Location = new System.Drawing.Point(299, 330);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(100, 41);
this.button2.TabIndex = 0;
this.button2.Text = "send";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(430, 399);
this.Controls.Add(this.listBox1);
this.Controls.Add(this.textBox3);
this.Controls.Add(this.textBox2);
this.Controls.Add(this.textBox1);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.Text = "UDP sever";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.Button button2;
}
}
実験
両方起動後通信見てみる結果
ひとまず通信はできた様子でした。