質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.54%

  • VB.NET

    916questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • VB

    303questions

    VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

  • TCP

    163questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。

TCP通信でのサブスレッドの終了

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 1,143

abanda

score 4

前提・実現したいこと

ここに質問したいことを詳細に書いてください
他サイトの掲示板でも質問しているのですが、こちらでも質問させてください。

とあるサイトのサンプルからTCP通信のフォームアプリケーションを作ろる為に勉強しています。
そのサイトのサンプルではサーバー側とクライアント側をラジオボタンによって切り分けています。
私はそれをサーバー側とクライアント側に分けて、二つのフォームアプリケーションを作ろうとしています。
ほとんどサンプルを流用しているので、TCP通信のところは問題なく繋がったのですが、
サーバー側のアプリケーションでクライアントからの接続を待機中のスレッドを終了させようとするとフリーズしてしまいます。
サンプルでは特に問題なく終了できるのになぜ私の方では固まるのかがわかりません。
スレッドやTCP通信等に触れるのも初めてのことであり、何か根本的に理解できていない部分もあるのではないかと思い、質問させて頂きました。

また、サブスレッドをAbortで終了させるのもあまりよくないと聞きます。
接続待機中のスレッドを終了させる方法が何かありましたら、そちらもお聞きしたいと思います。

発生している問題・エラーメッセージ

TcpListenerがクライアント接続を待機中にストップボタンを押して、サブスレッドを終了しようとすると固まる。

###該当のソースコード

ここに言語を入力
ここにご自身が実行したソースコードを書いてください
```
Imports System.Net.Sockets
Imports System.Threading

Public Class Form1
'サーバー設定
Dim server As TcpClient = Nothing
'サーバーのリスナー設定
Dim listener As TcpListener = Nothing
'サーバーのセカンドスレッドの設定
Dim threadServer As Thread = Nothing

'デリゲート宣言
'別スレッドからメインスレッドのテキストボックスに書き込むデリゲート
Delegate Sub dlgWriteText(ByVal text As String)

'引数を持たない汎用のデリゲート
'ストップボタンを押す等に使用
Delegate Sub dlgMydelegate()

'ソケット通信の開始処理
'Startボタン押下
Private Sub StartServerbtn_Click(sender As Object, e As EventArgs) Handles StartServerbtn.Click
StartSock()
End Sub

'ソケット通信開始
Private Sub StartSock()
'サーバースタート
Dim OpenFlg As Boolean

OpenFlg = ServerStart()
picIndicator.BackColor = Color.Green

'ボタンのenableを変える
If OpenFlg Then
StartServerbtn.Enabled = False
StopServerbtn.Enabled = True
End If
End Sub

'セカンドスレッドの作成とサーバーのスタート
Private Function ServerStart() As Boolean

'ListenするIPアドレス
Dim ipString As String
Dim ipAdd As System.Net.IPAddress

'Listenするポート番号
Dim port As Integer

'サーバーのIPアドレス(または、ホスト名)とポート番号をテキストボックスから取得
ipString = textBoxIp.Text
ipAdd = System.Net.IPAddress.Parse(ipString)
port = Integer.Parse(textBoxPortNo.Text)

'TcpListenerを使用してサーバーの接続の確立
Try

'lisenerが無い場合
If listener Is Nothing Then
listener = New TcpListener(ipAdd, port)
End If
'クライアント接続要求の受付開始
listener.Start()

'スレッドの作成と開始
threadServer = New Thread(New ThreadStart(AddressOf ServerListen))
threadServer.Start()
Return True

Catch ex As Exception
'エラーが起きた
listener.Stop()
picIndicator.BackColor = Color.Navy
Return False
End Try
End Function

Private Sub ServerListen()

'クライアントの要求があったら、接続を確立する
'クライアントの要求が有るまでここで待機する 
server = listener.AcceptTcpClient()

'インジケータの色を変える
'バックカラーの変更はデリゲートの必要は無し
picIndicator.BackColor = Color.LightGreen

'クライアントとの間の通信に使用するストリームを取得
Dim stream As NetworkStream = server.GetStream()

'受信文字が入る。
'この数字は少なくても可、少ない場合はLoopが何回か実行される
Dim bytes(1000) As Byte

'受信が無い場合はここで待機する
'文字受信が有った場合とクライアントが接続を切った場合に
'次のステップに進む
Dim intCount As Integer = stream.Read(bytes, 0, bytes.Length)

End Sub

Private Sub StopServerbtn_Click(sender As Object, e As EventArgs) Handles StopServerbtn.Click
StopSock()
End Sub

Private Sub StopSock()
'サーバーストップ
CloseServer()

StartServerbtn.Enabled = True
StopServerbtn.Enabled = False

End Sub

'サーバーのクローズ
Private Sub CloseServer()
'サーバーのインスタンスが有って、接続されていたら
If server IsNot Nothing AndAlso server.Connected Then
server.Close()
End If
Try
'スレッドは必ず終了させること
If threadServer IsNot Nothing Then
threadServer.Abort()
End If
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
End Try

'インディケータの色を変える            
picIndicator.BackColor = Color.Navy

End Sub

End Class

試したこと

課題に対してアプローチしたことを記載してください

補足情報(言語/FW/ツール等のバージョンなど)

より詳細な情報
.NET Framework4.5
言語:Visual Basic
Windowsフォームアプリケーション

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

Threadのlistener.AcceptTcpClientで戻ってきていない為、終了時のthreadServer.Abortでスレッドが終わるのを待ってしまい制御が戻ってこなくなっています。
ですので、threadServer.Abortする前にlistener.Stopしてやればいいと思います。

listener.StopするとAcceptTcpClientでExceptionが発生しますので注意してください。

また、現状の作りだとスレッドの方でExceptionを処理すればスレッドも終了するのでAboutする必要もないと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/02/19 22:02

    Stopボタンで止まらず、abortも使わずに済みました。ありがとうございます。

    ”Threadのlistener.AcceptTcpClientで戻ってきていない”というのがまだちゃんとわかっていませんが、もっと勉強をしようと思います。
    またよろしくお願いします。

    キャンセル

  • 2017/02/19 22:37

    AcceptTcpClientはクライアントから接続要求が来るまで、その処理内で待ち続けます。
    ですので、AcceptTcpClientをコールすると接続要求が来るまで次の行が実行されなくなります。
    これにより、ThreadをAbortしようとしても、終了しないためにAbortもThreadが終了するまで待ち続けることになります。

    キャンセル

  • 2017/02/20 22:57

    なるほど! そういうことだったのですね
    補足説明ありがとうございます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.54%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • VB.NET

    916questions

    Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

  • VB

    303questions

    VB(ビジュアルベーシック)はマイクロソフトによってつくられたオブジェクト指向プログラミング言語のひとつで、同社のQuickBASICが拡張されたものです。VB6の進化版といわれています。

  • TCP

    163questions

    TCP(Transmission Control Protocol)とは、トランスポート層のプロトコルで、コネクション型のデータサービスです。