プロが教えるわが家の防犯対策術!

TCP/IP通信のクライアントプログラムをVC#で作成しております。
のん様が配布されているTCP/IPテストツール↓をサーバー側として、テスト通信しております。
 http://www.vector.co.jp/soft/dl/winnt/net/se4112 …

クライアントプログラムからテストツールにコマンド送信できていることは確認いたしました。
ただ、テストツールから「OK\n」をTEXT送信をした後、doループ処理から抜けられず、強制終了してしまいます。

強制終了時に表示されるメッセージは以下の通りとなります。
-----
System.IO.IOException: 転送接続からデータを読み取れません: 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。。 ---> System.Net.Sockets.SocketException: 接続済みの呼び出し先が一定の時間を過ぎても正しく応答しなかったため、接続できませんでした。または接続済みのホストが応答しなかったため、確立された接続は失敗しました。
場所 System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
場所 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- 内部例外スタック トレースの終わり ---
場所 System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
:
-----

doループ処理の終了条件(NetworkStreamに読み取り対象のデータがない、もしくは受信したデータの終端が\n)が満たされないまま、タイムアウトしてしまっているのだと思います。

質問:どのように修正すれば、想定している動作(クライアントプログラムからテストツールにコマンド送信、テストツールからOK\nを受信して終了)になるか、ご教示いただけませんでしょうか?

よろしくお願いいたします。

-----クライアントプログラムのソースコード抜粋
private void Send(string data){
TcpClient tcp = new TcpClient(txt_IP.Text, int.Parse(txt_Port.Text));

NetworkStream ns = tcp.GetStream();
ns.ReadTimeout = 5000;
ns.WriteTimeout = 5000;

byte[] sendBytes = Encoding.UTF8.GetBytes(data + "\n");
ns.Write(sendBytes, 0, sendBytes.Length); // ←コマンド送信はできている

MemoryStream ms = new MemoryStream();
byte[] resBytes = new byte[256];
int resSize = 0;
do {
resSize = ns.Read(resBytes, 0, resBytes.Length);
if (resSize == 0) {
break;
}
ms.Write(resBytes, 0, resSize);
} while (ns.DataAvailable || resBytes[resSize - 1] != '\n'); // ←ここから抜けられない

string resMsg = Encoding.UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
ms.Close();
resMsg = resMsg.TrimEnd('\n');

ns.Close();
tcp.Close();
}

質問者からの補足コメント

  • > テストツールが改行無しの"OK"だけ返している可能性はないかな
    可能性が高いため、真っ先に確認しました。
    resSize = ns.Read(resBytes, 0, resBytes.Length);
    の後に
    string contents = Encoding.UTF8.GetString(resBytes);
    として、contentsを確認しましたが、「OK¥n」を受信しているようです。

    > タイムアウト前にテストツール側でセッションを閉じればReadからresSizeゼロで返って正常終了できる
    その通りで、タイムアウト前にテストツール側を切断してしまえば、問題なくif (resSize == 0)に入り、正常終了しております。

    No.1の回答に寄せられた補足コメントです。 補足日時:2022/11/23 10:17

A 回答 (2件)

テストツールが改行無しの"OK"だけ返している可能性はないかな。

コード的には続く改行を待ってタイムアウトしそう。タイムアウトしたら例外を返すはずなので例外処理しておかないとプログラムは強制終了する。
タイムアウト前にテストツール側でセッションを閉じればReadからresSizeゼロで返って正常終了できるかもだけど。

とりあえず実際にネットワークを流れるパケットがどうなっているか確認するのが肝でしょう。ネットワークをモニタできるツールを入れて確認すれば?
あとはReadから返ったところでprint文でも書いてどこまで受信できているか確認するとか。
この回答への補足あり
    • good
    • 0

(1) テストツール側に開発プログラムから受信したデータと返信したデータをダンプする機能をそれぞれ適切な場所へ入れる。


(2) 開発プログラムの「サーバとの接続成功」、「サーバーへの送信成功」、「サーバーからの受信成功」のことろにメッセージ出力を入れて進み具合を目視確認できるようにする。

ちなみに(2)はコンパイルオプションで機能のON/OFFが出来るようにしておくと便利です。
で、「サーバーからの受信成功」のメッセージ表示がされないのであればテストツール側の問題。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A