動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
TCPで送信して応答を受信する実装をしてみた。
関連
code v0.1
MainWindow.xaml
<Window x:Class="WPF_TCPClient_171205.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPF_TCPClient_171205"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid Background="LightGray">
<Button Name="B_send" Content="Send" HorizontalAlignment="Left" Margin="432,67,0,0"
VerticalAlignment="Top" Width="75" Click="B_send_Click"/>
<Label Content="Text" HorizontalAlignment="Left" Margin="10,64,0,0" VerticalAlignment="Top"/>
<TextBox Name="T_sendText" HorizontalAlignment="Left" Height="23" Margin="58,65,0,0"
TextWrapping="Wrap" Text="Hello" VerticalAlignment="Top" Width="357"/>
<TextBox Name="T_log" HorizontalAlignment="Left" Height="215" Margin="10,94,0,0"
TextWrapping="Wrap" VerticalAlignment="Top" Width="497"
VerticalScrollBarVisibility="Visible"
Text="{Binding LogText}"/>
<Label Content="SendTo" HorizontalAlignment="Left" Margin="10,9,0,0" VerticalAlignment="Top"/>
<TextBox Name="T_sendTo" HorizontalAlignment="Left" Height="23" Margin="68,10,0,0"
TextWrapping="Wrap" Text="192.168.0.79" VerticalAlignment="Top" Width="120"/>
<Label Content="port" HorizontalAlignment="Left" Margin="229,9,0,0" VerticalAlignment="Top"/>
<TextBox Name="T_port" HorizontalAlignment="Left" Height="23" Margin="268,10,0,0"
TextWrapping="Wrap" Text="7000" VerticalAlignment="Top" Width="120"/>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//以下を追加した
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.ComponentModel;
using System.IO;
namespace WPF_TCPClient_171205
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
static private TcpClient s_tcpClient;
static private string _logText = string.Empty;
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private bool TCP_connect(string ipAddress, string portStr)
{
if (int.TryParse(portStr, out int portInt) == false)
{
return false;
}
s_tcpClient = new TcpClient(ipAddress, portInt);
s_tcpClient.Client.ReceiveTimeout = 300; // msec
s_tcpClient.Client.Blocking = true; // *** 1
return true;
}
private void TCP_disconnect()
{
s_tcpClient.Close();
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName = null)
{
if (PropertyChanged != null)
PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string LogText
{
get { return _logText; }
set
{
_logText = value;
OnPropertyChanged("LogText");
}
}
private void TCP_send(string ipadr, string portStr, string text)
{
if (int.TryParse(portStr, out int portInt) == false)
{
return; // error
}
if (TCP_connect(T_sendTo.Text, T_port.Text) == false)
{
return; // error
}
using (var netStream = s_tcpClient.GetStream())
{
using (var sWriter = new StreamWriter(netStream, Encoding.ASCII))
{
// 1. 送信
sWriter.WriteLine(text);
sWriter.Flush();
// 2. 受信
ReceiveData(netStream);
}
}
TCP_disconnect();
}
private void ReceiveData(NetworkStream netStream)
{
// 1. rcvdは<CR><LF>付き
byte[] ReceiveBytes = new byte[1024];
int BytesReceived = netStream.Read(ReceiveBytes, 0, ReceiveBytes.Length);
string rcvd = Encoding.ASCII.GetString(ReceiveBytes, 0, BytesReceived);
// 2. rcvdは<CR><LF>なし
//var sReader = new StreamReader(netStream, Encoding.ASCII);
//string rcvd = sReader.ReadLine();
//
LogText += rcvd;
}
private void B_send_Click(object sender, RoutedEventArgs e)
{
TCP_send(T_sendTo.Text, T_port.Text, T_sendText.Text);
}
}
}
実行例
接続先にはVisual Studio | WPF > TCPサーバ > echo server > 1対N通信 > ThreadPool.QueueUserWorkItem()使用 v0.1, v0.2
のソフトを起動し、Listenボタンを押しておく。
備考
受信処理
受信処理はReceiveData()の2種類の処理で受信できている。
1の場合(Read)ではCR,LFのコード付きでLogTextに入る。
2の場合(ReadLine)ではCR, LFのコードなしでLogTextに入る。
Blocking
s_tcpClient.Client.Blocking
をtrueとしている。
falseにするとGetStream()においてエラーが出る。
System.IO.IOException: '操作は非ブロッキング ソケットでは実行できません。'