

掲題のエラーがクライアント、サーバ間のソケット通信をc#で実施していたところ発生しました。

何が原因で発生しているかが知りたいです。

■クライアント側ソース

[code]

    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;
                }
    
            }
        }
    
    
    
    }
    
[/code]

■サーバ側ソース

[code]

    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 = "サーバー終了";
                }
    
            }
    
    
            }
        }
    
[/code]


CC BY-SA 3.0
2017-03-23T01:07:10.253
33469
2017-03-23T02:18:36.503
2017-03-23T02:18:36.503
21161
question
c# visual-studio
System.Net.Sockets.Socket.Exception ＜追加情報＞ブロック操作はWSACancelBlockingCallの呼び出しに割り込まれました


別のスレッドでソケットを閉じた場合などに`Accept`などのブロッキング呼び出しで発生する仕様通りの例外です。発生個所で適切にキャッチなどをしていれば特に問題はありません。


CC BY-SA 3.0
2017-03-23T02:15:31.597
33474
2017-03-23T02:15:31.597
5750
33469
answer