DOBON.NETプログラミング道掲示板
(現在 過去ログ2 を表示中)

[ 最新記事及び返信フォームをトピックトップへ ]

■33748 / inTopicNo.1)  VB.NETでの TCPClient通信をByteのみでしょうか?
  
□投稿者/ シロ 一般人(1回)-(2017/12/06(Wed) 18:01:17)
  • アイコン環境/言語:[windows7 / VB.Net 2015 / Framework4.7.02053] 
    分類:[.NET] 

    プログラム初心者です。
    ごく当たり前の質問なのかもしれませんが、教えて下さい。

    現在、TCP/IPを使用したターミナルソフト(teraterm使用)で特定のテキストコ
    マンドを送信すると、自動で返信があるシステムがあります。
    (”Time”と送信すると、現地の時間13:00を返すようなシンプルなものです)

    vb.netで"Time"コマンドを自動で送信し、取得して記録するようなプログラムを
    組みたいのでdobon.net様内のTcpClientのコードを参考に作ろうかと考えていま
    したが”Time”と送信しても”Time”と返信がある状態になり、原因がわからず。

    そもそも、この場合でもbyte型への変換が必要になるのでしょうか?

    textで送信、textで受信している為、変換が必要ないのでは?と思い他のコード
    を探しましたが、string型等で送受信しているものが見当たりませんでした。

    その他の方法があるのでしょうか?


    以下、ほぼそのままなので申し訳ないのですがコードです。

    'サーバーに送信するデータを入力してもらう
    Console.WriteLine("文字列を入力し、Enterキーを押してください。")
    Dim sendMsg As String = Console.ReadLine()
    '何も入力されなかった時は終了
    If sendMsg Is Nothing OrElse sendMsg.Length = 0 Then
    Return
    End If

    'サーバーのIPアドレス(または、ホスト名)とポート番号
    Dim ipOrHost As String = "192.168.1.10"
    'Dim ipOrHost As String = "localhost"
    Dim port As Integer = 10001

    'TcpClientを作成し、サーバーと接続する
    Dim tcp As New System.Net.Sockets.TcpClient(ipOrHost, port)
    Console.WriteLine("サーバー({0}:{1})と接続しました({2}:{3})。",
    DirectCast(tcp.Client.RemoteEndPoint, System.Net.IPEndPoint).Address,
    DirectCast(tcp.Client.RemoteEndPoint, System.Net.IPEndPoint).Port,
    DirectCast(tcp.Client.LocalEndPoint, System.Net.IPEndPoint).Address,
    DirectCast(tcp.Client.LocalEndPoint, System.Net.IPEndPoint).Port)

    'NetworkStreamを取得する
    Dim ns As System.Net.Sockets.NetworkStream = tcp.GetStream()

    '読み取り、書き込みのタイムアウトを10秒にする
    'デフォルトはInfiniteで、タイムアウトしない
    '(.NET Framework 2.0以上が必要)
    ns.ReadTimeout = 10000
    ns.WriteTimeout = 10000

    'サーバーにデータを送信する
    '文字列をByte型配列に変換
    Dim enc As System.Text.Encoding = System.Text.Encoding.UTF8
    Dim sendBytes As Byte() = enc.GetBytes(sendMsg & ControlChars.Lf)
    'データを送信する
    ns.Write(sendBytes, 0, sendBytes.Length)
    Console.WriteLine(sendMsg)

    'サーバーから送られたデータを受信する
    Dim ms As New System.IO.MemoryStream()
    Dim resBytes As Byte() = New Byte(255) {}
    Dim resSize As Integer = 0
    Do
    'データの一部を受信する
    resSize = ns.Read(resBytes, 0, resBytes.Length)
    'Readが0を返した時はサーバーが切断したと判断
    If resSize = 0 Then
    Console.WriteLine("サーバーが切断しました。")
    Exit Do
    End If
    '受信したデータを蓄積する
    ms.Write(resBytes, 0, resSize)
    'まだ読み取れるデータがあるか、データの最後が\nでない時は、
    ' 受信を続ける
    Loop While ns.DataAvailable OrElse
    resBytes(resSize - 1) <> AscW(ControlChars.Lf)
    '受信したデータを文字列に変換
    Dim resMsg As String = enc.GetString(ms.GetBuffer(), 0, CInt(ms.Length))
    ms.Close()
    '末尾の\nを削除
    resMsg = resMsg.TrimEnd(ControlChars.Lf)
    Console.WriteLine(resMsg)

    '閉じる
    ns.Close()
    tcp.Close()
    Console.WriteLine("切断しました。")

    Console.ReadLine()

引用返信 削除キー/
■33755 / inTopicNo.2)  Re[1]: VB.NETでの TCPClient通信をByteのみでしょうか?
□投稿者/ Azulean 大御所(489回)-(2017/12/08(Fri) 00:02:33)
  • アイコンNo33748に返信(シロさんの記事)
    > そもそも、この場合でもbyte型への変換が必要になるのでしょうか?
    >
    > textで送信、textで受信している為、変換が必要ないのでは?と思い他のコード
    > を探しましたが、string型等で送受信しているものが見当たりませんでした。

    変換は必要です。
    というのも、.NET の文字列型としては "Time" という単一の表現であっても、それに対応するバイト表現は何通りもあるので、開発者がどのバイト表現をとるべきかを意識しなければなりません。
    そういう意味で、自分でバイト型に変換してから渡すことが必要となります。

    UTF-8 を選んでいるようですが、おそらくは ASCII なのでしょうね。
    (半角英数の範囲において、UTF-8 と ASCII のバイト表現は同じなので、そこが原因ではなさそうです)


    > vb.netで"Time"コマンドを自動で送信し、取得して記録するようなプログラムを
    > 組みたいのでdobon.net様内のTcpClientのコードを参考に作ろうかと考えていま
    > したが”Time”と送信しても”Time”と返信がある状態になり、原因がわからず。

    コードを読む限り、送信して受信を始める前に一度自分で Console.WriteLine で送った文字列を画面に表示しています。
    つまり、

    (入力)Time
    (出力)サーバー(xxx.xxx.xxx.xxx:xx)と接続しました(yyy.yyy.yyy.yyy:yy)
    (出力)Time
    (出力)[受信した文字列]
    (出力)切断しました。

    となることを期待しています。
    さて、画面には受信した文字列として Time が表示される、つまり、出力で 2 行、Time が続いたという状況ですか?
    それとも、勘違いして、3行目の「受信した文字列」の部分が画面に出ていない状態ですか?

    また、送信時は "Time" という文字列だけで良いのか、末尾に改行を加えないといけないのか、どちらですか?
    (今のコードは改行が含まれていません)
引用返信 削除キー/
■33756 / inTopicNo.3)  Re[1]: VB.NETでの TCPClient通信をByteのみでしょうか?
□投稿者/ まりもん 一般人(3回)-(2017/12/08(Fri) 09:32:30)
  • アイコン"Time"を受信しているとしてですが

    その"Time"はエコーバックだったりしませんか?
    また、コマンドの終了は現状[LF]のみとなっているみたいですが[CR][LF]だったりしませんか?
引用返信 削除キー/
■33758 / inTopicNo.4)  Re[2]: VB.NETでの TCPClient通信をByteのみでしょうか?
□投稿者/ シロ 一般人(2回)-(2017/12/16(Sat) 09:24:00)
  • アイコンNo33755に返信(Azuleanさんの記事)
    No33756に返信(まりもんさんの記事)

    返信ありがとうございます。
    バイトへの変換が必要ということがわかった為、変換ありきとして試した結果無事送受信が可能になりました。

    見えていたものはローカルエコーでした。
    また、返信のない原因は接続先の機器の問題で「LF」を送信すると止まってしまう為、でした。

    大変ありがとうございました。
引用返信 削除キー/



トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

Mode/  Pass/


- Child Tree -