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

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

新規登録して質問してみよう
ただいま回答率
85.48%
VB

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

TCP

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

VB.NET

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

Q&A

解決済

1回答

8044閲覧

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

abanda

総合スコア12

VB

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

TCP

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

VB.NET

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

0グッド

0クリップ

投稿2017/02/18 14:02

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

とあるサイトのサンプルから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フォームアプリケーション

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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

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

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

投稿2017/02/19 09:19

YAmaGNZ

総合スコア10242

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

abanda

2017/02/19 13:02

Stopボタンで止まらず、abortも使わずに済みました。ありがとうございます。 ”Threadのlistener.AcceptTcpClientで戻ってきていない”というのがまだちゃんとわかっていませんが、もっと勉強をしようと思います。 またよろしくお願いします。
YAmaGNZ

2017/02/19 13:37

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

2017/02/20 13:57

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問