Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
TCPクライアントのソフトを実装中に持った疑問が、相手先がいない場合のタイムアウト処理だった。
実装案
下記を見つけた。
How to set the timeout for a TcpClient?
answered Jun 14 '13 at 23:30
Jonさんによる回答ではBeginConnect()などの処理を使っている。
EndConnect()処理の扱いなど使うことになるため、この方法は使わない。
answered Jun 18 '15 at 13:53
Simon Mourierさんによる.NET 4.5以降では有効との処理を使う。
code
<Window x:Class="_171207_t1540_tcpConnectFail.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:_171207_t1540_tcpConnectFail"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Name="B_connect" Content="Connect" Height="30"
Click="B_connect_Click"/>
</Grid>
</Window>
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 _171207_t1540_tcpConnectFail
{
/// <summary>
/// MainWindow.xaml の相互作用ロジック
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void B_connect_Click(object sender, RoutedEventArgs e)
{
String ipadr = "192.168.0.79";
int port = 7000;
var client = new TcpClient();
if (client.ConnectAsync(ipadr, port).Wait(1000) == false)
{
MessageBox.Show("Connect fail");
} else {
MessageBox.Show("Connect OK");
}
client.Close();
}
}
}
動作環境
.NET Framework バージョン判定(4.5から4.7.1) by @jTakasuRyuji さん
によると、レジストリでどの.NET Frameworkが入っているか確認できるらしい。
自分が使える環境の例として調べた。
- Windows 7: Releaseキー 見つからず (v4.5未満?)
- プログラムの機能と追加の「Windowsの機能」ではv3.5のみ
- Window 8.1: Releaseキー 見つからず
- OS Integrationにはv4(REG_DWORD)というキーは見つかった。
- プログラムの機能と追加の「Windowsの機能」ではv3.5とv4.5
結果
未消化の点
.NET Framework v3.5しか入っていないWindows 7でも接続失敗を認識した。
Simon Mourierさんの「Starting with .NET 4.5, TcpClient has a cool ConnectAsync method 」という意味が未消化。
ビルド時の環境がv4.5以降であれば良いのだろうか?
以下ではv2.0 SP1以降であればConnectAsync()が使えるような記載がされている。
https://stackoverflow.com/questions/5764921/whats-the-difference-between-beginconnect-and-connectasync
Prefer ConnectAsync when possible (though it requires min .NET 2.0 SP1).