Public Class MyTcpClient
    Inherits System.Net.Sockets.TcpClient

    Protected enc As System.Text.Encoding = System.Text.Encoding.GetEncoding("shift-jis")  '上記配列のエンコード用
    Protected sw As System.IO.StreamWriter              '文字列書き込みストリーム
    Protected sr As System.IO.StreamReader              '文字列読み込みストリーム

    Public srThraed As System.Threading.Thread    '読み取りスレッド
    Public srThraedFlag As Boolean

    'クライアント用コンストラクタ
    Public Sub New(ByVal host As String, ByVal portNo As Integer)
        MyBase.New(host, portNo)
        Me.sw = New System.IO.StreamWriter(Me.GetStream(), Me.enc) '書き込み用のストリーム作成
        Me.sr = New System.IO.StreamReader(Me.GetStream(), Me.enc) '読み込み用のストリーム作成

        Dim readThreadDelegate As New System.Threading.ThreadStart(AddressOf Me.ReadTread) '読み取りメソッドを記憶
        Me.srThraed = New System.Threading.Thread(readThreadDelegate)
        Me.srThraed.Start() '読み取りスレッド起動
    End Sub

    'コンストラクタ2
    Public Sub New(ByVal socket As System.Net.Sockets.Socket)
        Me.Client = socket
        Me.sw = New System.IO.StreamWriter(Me.GetStream(), Me.enc) '書き込み用のストリーム作成
        Me.sr = New System.IO.StreamReader(Me.GetStream(), Me.enc) '読み込み用のストリーム作成

        Dim readThreadDelegate As New System.Threading.ThreadStart(AddressOf Me.ReadTread) '読み取りメソッドを記憶
        Me.srThraed = New System.Threading.Thread(readThreadDelegate)
        Me.srThraed.Start() '読み取りスレッド起動
    End Sub

    ' ローカル エンドポイントを取得
    Public ReadOnly Property LocalEndPoint() As System.Net.IPEndPoint
        Get
            LocalEndPoint = Me.Client.LocalEndPoint
        End Get
    End Property

    'リモート エンドポイントを取得
    Public ReadOnly Property RemoteEndPoint() As System.Net.IPEndPoint
        Get
            RemoteEndPoint = Me.Client.RemoteEndPoint
        End Get
    End Property

    Public Sub Write(ByVal msg As String)
        Me.sw.Write(msg)
        Me.sw.Flush()
    End Sub

    Public Sub WriteLine(ByVal msg As String)
        Me.sw.Write(msg)
        Me.sw.Write(System.Environment.NewLine)
        Me.sw.Flush()
    End Sub

    Public Sub WriteLine()
        Me.sw.Write(System.Environment.NewLine)
        Me.sw.Flush()
    End Sub

    Public Sub ReadTread()
        Try
            Me.srThraedFlag = True
            Do While Me.srThraedFlag
                Dim s As String = sr.ReadLine()
                If s Is Nothing Then Exit Sub
                Receive(s)
            Loop
        Catch ex As Exception
            Me.Close()
        End Try
    End Sub

    '1行受信したら呼ばれるメソッド
    Public Overridable Sub Receive(ByVal msg As String)
        Console.WriteLine(msg)
    End Sub

    'スタート
    Public Shared Sub Main()
        Dim client As MyTcpClient
        Try
            Console.WriteLine("TCP/IPクライアントソフトです")
            Dim ipHost As System.Net.IPHostEntry = System.Net.Dns.Resolve(System.Net.Dns.GetHostName()) '使用しているマシンのipとホスト管理
            Console.WriteLine("このマシンのIPアドレス:" & ipHost.AddressList(0).ToString())

            Console.Write("接続サーバーのIPアドレス>")
            Dim ip As String = Console.ReadLine()
            Console.Write("接続ポート番号>")
            Dim portNo As Integer
            Dim s As String = Console.ReadLine()
            portNo = s
            client = New MyTcpClient(ip, portNo) '接続
            Console.Write("リモートホストアドレス:" & client.RemoteEndPoint.Address.ToString)
            Console.WriteLine(", ポート :" & client.RemoteEndPoint.Port)
            Console.Write("ローカルホストアドレス:" & client.LocalEndPoint.Address.ToString)
            Console.WriteLine(", ポート :" & client.LocalEndPoint.Port)
            Do
                s = Console.ReadLine()
                client.WriteLine(s)
            Loop While s <> "end"
        Catch ex As Exception
            Console.WriteLine(ex.ToString())

        End Try
    End Sub
End Class