System.Net.Sockets.Socket.Exception <追加情報>ブロック操作はWSACancelBlockingCallの呼び出しに割り込まれました
掲題のエラーがクライアント、サーバ間のソケット通信をc#で実施していたところ発生しました。
何が原因で発生しているかが知りたいです。
■クライアント側ソース
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "クライアント"; // フォームのタイトル名
button1.Text = "送信"; // 送信ボタンの表示文字
label1.Text = ""; // 状態表示用ラベルを初期化
textBox1.Text = "aあbいcうd"; // 送信用データ
}
private void button1_Click(object sender, EventArgs e)
{
// TCPクライアントを生成
System.Net.Sockets.TcpClient client = new System.Net.Sockets.TcpClient(); // TCPクライアント
label2.Text = ""; // 受信データ表示用ラベルの初期化
try
{
// TCP/IP接続を行う
client.Connect("127.0.0.1", 9000);
// 通信ストリームの取得
System.Net.Sockets.NetworkStream stream = client.GetStream();
// サーバーへ送信
byte[] SendBuffer = System.Text.Encoding.Unicode.GetBytes(textBox1.Text);
stream.Write(SendBuffer, 0, SendBuffer.Length);
stream.Flush(); // フラッシュ(強制書き出し)
label1.Text = "送信成功"; // 正常に送信できた場合
// サーバーからの受信
byte[] ReceiveData = new byte[1000];
stream.Read(ReceiveData, 0, ReceiveData.Length);
label2.Text = "受信データ : " + System.Text.Encoding.Unicode.GetString(ReceiveData); // 正常に受信できた場合
// TCPクライアントをクローズ
client.Close();
}
catch (Exception ex)
{
// 接続できなかった場合
label1.Text = ex.Message;
}
}
}
}
■サーバ側ソース
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Windows;
namespace WindowsFormsApplication2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// スレッドからテキストボックスをアクセスすることを指定
Control.CheckForIllegalCrossThreadCalls = false;
}
// メンバー変数
private System.Net.Sockets.Socket ServerSocket; // ソケット
private System.Threading.Thread StartListeningThread; // 接続待ちスレッド
private volatile bool SLTAlive; // 接続待ちスレッド終了指示フラグ(volatile が指定されていることに注意)
// フォーム起動時イベント
private void Form1_Load(object sender, EventArgs e)
{
this.Text = "サーバー"; // フォームのタイトル名
button1.Text = "サーバー開始"; // 開始ボタンの表示文字
button2.Text = "サーバー終了"; // 終了ボタンの表示文字
label1.Text = ""; // 状態表示用ラベルを初期化
// スレッド終了指示フラグを未終了に初期化
SLTAlive = false;
}
// フォーム閉鎖時イベント
private void Form1_FormClosed(object sender, FormClosedEventArgs e)
{
if (SLTAlive)
{
if (ServerSocket != null)
{
// 接続要求受け入れの終了
ServerSocket.Close();
}
// 念のためスレッドをnull設定
StartListeningThread = null;
// スレッド終了指示フラグを終了に設定
SLTAlive = false;
}
}
// 接続待ち開始ボタンのクリックイベント
private void button1_Click(object sender, EventArgs e)
{
if (!SLTAlive) // まだ接続待ちスレッドを生成していない場合
{
// Socket の生成
ServerSocket = new System.Net.Sockets.Socket(
System.Net.Sockets.AddressFamily.InterNetwork, // IP version 4 のアドレス
System.Net.Sockets.SocketType.Stream, // 通信方式をバイトストリーム
System.Net.Sockets.ProtocolType.Tcp); // プロトコルをTCP
// ホストのIPアドレスとポート番号の指定
System.Net.IPEndPoint EndPointHost = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 9000);
// *** System.Net.IPEndPoint EndPointHost = new System.Net.IPEndPoint(System.Net.IPAddress.Any, 9000);
ServerSocket.Bind(EndPointHost); // ローカル エンドポイント(IPアドレス等の情報)と関連付け
ServerSocket.Listen(100); // 電文取り出しの接続がまだ保留中におけるキューの最大長
// 接続待ち用スレッドを作成
StartListeningThread = new System.Threading.Thread(StartListening);
// 接続待ち用スレッドを開始
StartListeningThread.Start();
// スレッド終了指示フラグを未終了に設定
SLTAlive = true;
}
}
private void button2_Click(object sender, EventArgs e)
{
if (SLTAlive) // 接続待ちスレッドが作成されていて使える場合
{
if (ServerSocket != null)
{
// 接続要求受け入れの終了
ServerSocket.Close();
}
// スレッド終了指示フラグを終了に設定
SLTAlive = false;
label1.Text = "サーバー終了";
}
}
//============
// 接続待ちスレッド用メソッド
private void StartListening()
{
label1.Text = "サーバー開始";
try
{
// 受信の受付を行なうための無限ループ
while (SLTAlive) // スレッド終了指示フラグでの終了指示がある場合はループ終了
{
// クライアントからの接続を受け付ける
System.Net.Sockets.Socket ClientSocket = ServerSocket.Accept(); // Socketクライアント
// クライアントからの電文の受信
byte[] ReceiveData = new byte[2000];
int ResSize = ClientSocket.Receive(
ReceiveData, ReceiveData.Length,
System.Net.Sockets.SocketFlags.None); // 受信
string str = System.Text.Encoding.Unicode.GetString(ReceiveData);
textBox1.Text = str; // 受信データ
Process p = new Process();
p.StartInfo.FileName = System.Environment.GetEnvironmentVariable("ComSpec");
string batchFile = @"C:\yahoo.bat";
//trueにすると、コマンドプロンプトが一瞬現れた
p.StartInfo.UseShellExecute = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.Arguments = string.Format(@"/c {0}", batchFile);
p.Start();
p.WaitForExit();
p.Close();
// 返信電文をクライアントへ送信
byte[] SendBuffer = Encoding.Unicode.GetBytes("本サーバーの御利用ありがとう御座います。");
int i = ClientSocket.Send(SendBuffer);
// Socketクライアントをクローズ
ClientSocket.Shutdown(System.Net.Sockets.SocketShutdown.Both);
ClientSocket.Close();
}
}
catch (Exception ex)
{
label1.Text = "サーバー終了";
}
}
}
}