C#で通信処理。応答がない場合、すぐエラーにしたい

このQ&Aのポイント
  • C#で通信処理を行う際に、応答が遅い場合にすぐにエラーを発生させたいと思っています。
  • 指定したIPアドレスが存在しない場合のエラー応答について、即時返答はできないのか疑問があります。
  • また、データの送信後にデータが返ってこない場合にどのように待機時間を設定するかも悩んでいます。
回答を見る
  • ベストアンサー

C#で通信処理。応答がない場合、すぐエラーにしたい

VS2005、C#で通信処理をしています。 やりたいことは「接続後、データを渡してその返答データをもらう」です。 //サーバーに接続 Int32 port = 9999; TcpClient client = new TcpClient(server, port); //サーバーにメッセージを送信 Byte[] dataA = System.Text.Encoding.UTF8.GetBytes(message); Byte[] dataB = Byte[128]; NetworkStream stream = client.GetStream(); stream.Write(dataA, 0, dataA.Length); len = stream.Read(dataB, 0, dataB.Length) client.Close(); ネットのサンプルを参考にさせてもらい、上のようなソースを作ることができたのですが、2つの疑問があります。 (1)接続時に指定したIPアドレスが存在しない場合、エラーが返ってくるのが遅いです。そういうものなのでしょうか。たとえば、即時返答などはできないのでしょうか。 (2)接続してデータを送っても、向こうからデータが返ってこなければずっと待機したままです。たとえばミリセカンドで切ることはできないのでしょうか。 もしくは指定のミリセカンド経過後強制的にエラー処理に飛ばす等はできないのでしょうか。 通信処理をやるのが初めてで定石がよくわからず、あれこれ試している状態です。 処理についてご存じの方、ご指南いただけたらと思います。参考になるサイトや検索キーワードだけでも教えていただけたら嬉しいです。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • OKwebb
  • ベストアンサー率44% (92/208)
回答No.1

C#は知らないのでアドバイスのみ。 この辺は使用しているクラスにそういう機能があるかどうか。 なければ、サーバのタイムアウトを待つしかない。 たとえば(2)であれば TcpClient.SendTimeout プロパティを設定しとけば Send メソッドが正常に完了する前にタイムアウトが発生した場合、TcpClient は SocketException をスローするらしいですよ。 詳細は参考URLのmsdn参照。

参考URL:
http://msdn.microsoft.com/ja-jp/library/system.net.sockets.tcpclient.sendtimeout(VS.80).aspx
lovesens
質問者

お礼

アドバイスありがとうございます。 client.SendTimeout = 100 を設定するとすぐに返ってくるようになりました。 ご指南に感謝いたします。

関連するQ&A

  • ソケットとそれに基づくストリームは1対1でしょうか。

    ソケット通信で、接続してきた クライアント(TcpClient tempclient)から、 NetworkStream,StreamReader,StreamWriterなどを 作っています。 Class A while(true){ tcpclient=server.AcceptClient(); networkstream=tcpclient.getStream(); streamreder=new StreamReader(networkstream...); mythread=new Mythread(tcpclient); // networkstream.close() streamreader.close() //これらを加えると、下の、/* */でエラーになります。 } MyThread B { Public Mythread(TcpCLient tcpclient){ /* ns=tcpclient.Getstream sr=... */ } このクライアントを、別のスレッドで使うため、 mythread=new MyThread(tcpclient)などとして、 別のクラスにもっていき、 そこでも、新たに、NetworkStream,StreamReaderを 作ったとします。 この場合、1つのクライアントにつき、2つの ストリームができるのでしょうか。 経験上、ストリームを作成するコードは 問題なく動きます。 しかし、新たにストリームを得たので、古いのを クローズすると、エラーになります。 新たに作ったストリームは、実は、古いストリームを、 使いまわしていることになるのでしょうか。 少し、分かりづらいかもしれませんが、 何か分かる人がいましたら、よろしくお願いします。

  • 簡単なネットワークプログラムなのですが・・・

    ネットワーク通信の基礎を学ぼうと、いろいろなサイトをみながらSocket通信の簡単なメッセージ送受信を行おうとしているのですが、streamを使って送信したメッセージを送信、又は受信するときにsocketを閉じないと送信できません。 そして常に受信させたいのですが、socketを閉じているため、nullexceptionになってしまいます。 何か別の手はありますでしょうか・・・? 現在↓のような感じで行っています。 private void 待機ToolStripMenuItem_Click(object sender, EventArgs e) { //サーバーを開始 Int32 port = 9999; IPAddress localAddr = IPAddress.Parse("127.0.0.1"); server = new TcpListener(localAddr, port); server.Start(); threadA = new Thread(recvData); threadA.Start(); } // 受信用(マルチスレッド) public void recvData() { //接続待機 this.Invoke(new MyDelegate(delegate { textBox1.Text = "接続待機中"; })); TcpClient client = server.AcceptTcpClient(); //接続 this.Invoke(new MyDelegate(delegate { textBox1.Text = "接続されました"; })); NetworkStream stream = client.GetStream(); // 無限ループ while (true) { Byte[] bytes = new Byte[20]; //わざと小さく取ってある。 int i; //メッセージを受信 while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) { String data = System.Text.Encoding.UTF8.GetString(bytes, 0, i); Console.WriteLine(String.Format("受信: {0}", data)); } client.Close(); }

  • 統計の問題

    統計学の問題を解いていただきたいです。今までスマホを使って解いていましたが、故障したため、できない状態です。パソコンはありません。 この質問は友達に投稿してもらっています。 dataA = c(18.3, 16.9, 18.1, 17.7, 17.9, 17.3, 18.7, 18.3, 16.3, 15.0, 17.9, 18.2, 15.3, 18.5, 16.9, 18.4, 17.4, 17.9, 17.8, 16.3, 17.4, 17.2, 16.7, 17.4, 17.7, 15.5, 17.3, 16.3, 15.1, 16.4) dataB = c(17.8, 19.1, 18.6, 17.6, 18.7, 19.2, 15.9, 18.9, 19.1, 18.7, 13.1, 16.2, 16.8, 18.5, 18.0, 17.5, 18.4, 16.1, 18.1, 16.3, 16.5, 17.2, 18.2, 15.9, 16.0, 17.7, 18.7, 18.8, 18.2, 18.6) ① それぞれのデータにおける「平均値(算術平均)」,「自由度」,「不偏分散」を求めよ. 平均値 mean(dataA) mean(dataB) 自由度 length(dataA)-1 length(dataB)-1 計算式で出した不偏分散 sum((dataA -mean(dataA))^2)/(length(dataA)-1) sum((dataB -mean(dataB))^2)/(length(dataB)-1) ② それぞれのデータにおける「標準誤差」および「95%信頼区間」を求めよ. 標準誤差 標準偏差 / sqrt(n) sqrt(var(dataA)) / sqrt(length(dataA)) sqrt(var(dataB)) / sqrt(length(dataB)) 95%信頼区間 mean(dataA)+(qnorm(0.95) * sd(dataA)) mean(dataA)-(qnorm(0.95) * sd(dataA)) mean(dataB)+(qnorm(0.95) * sd(dataB)) mean(dataB)-(qnorm(0.95) * sd(dataB)) ③ それぞれのデータを平均0,標準偏差1のデータにZ変換せよ. ④ 5%水準において,dataAとdataBの平均値に差があるかどうか判定せよ.なお,回答には対立仮説および帰無仮説を明記すること.また「入力したコマンド」や「出力結果」を示すとともに,「判定するために読み取った場所」および「なぜそのように判定したのか」を説明すること. t.test(x=dataA,y=dataB,conf.level=0.95,var.equal=F)

  • VB2005 で encoding="Shift_JIS"や"EUC-JP"のXMLファイルを保存する方法

    VB2005, XML の初心者です。 VB2005で encoding="Shift_JIS" や "EUC-JP" のXMLデータをファイルに保存するにはどうすれば良いのでしょうか。 encoding="UTF-8"であれば、下記で保存できますが、="Shift_JIS" や "EUC-JP" になると保存でエラーになってしまいます。 下記ソースでは、strXMLには正しくXMLが入っていますが、saveするとエラーになり、ファイルの中身を確認すると、日本語の箇所で切れていました。 Public Client As TcpClient Dim stream As NetworkStream stream = Client.GetStream() Dim Data(10000) As Byte Dim len As Int16 = stream.Read(Data, 0, Data.Length) strXML = System.Text.Encoding.UTF8.GetString(Data, 0, len) MsxmlDoc = New MSXML2.DOMDocument Msxmldoc.Loadxml(strXML) MsxmlDoc.save ( "C:\XML.xml") 文字コードについても初心者ですので、ヒントになるようなことでも教えていただければ幸いです。 よろしくお願い致します。

    • ベストアンサー
    • XML
  • vb.netのプロパティの使い方について

    こんにちわ! vb.netのプロパティの使い方がわからず困っています。 具体的にはTCPクライアント接続を行い、データ送信前に現在接続を行っているかチェックを行いたいです。 作ったのは↓ Public Class Form1 'ボタンを押したら Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click Dim tcp_conect As New System.Net.Sockets.TcpClient 'ソケット作成 Dim net_stream As System.Net.Sockets.NetworkStream = Nothing 'ストリーム取得 Dim send_bytes As Byte() = {&HFF, &H0} '送信データ tcp_conect.Connect("192.168.1.1", "2000") 'ソケット接続 net_stream = tcp_conect.GetStream() 'ソケットストリーム取得 If tcp_conect.conected = True Then 'エラーが出てしまう。 net_stream.Write(send_bytes, 0, send_bytes.Length) 'データ送信 End If tcp_conect.Close() 'ソケット閉じる End Sub End Class 'プロパティ Public Class TcpClient Dim _conect_test As Boolean Public ReadOnly Property Connected As Boolean Get Stop Return _conect_test End Get End Property End Class これでテストをしたいのですが、プロパティが実行されません。 もしかしてプロパティの使い方がそもそも違うのかもしれないのですが、、、 アドバイスのほどよろしくお願いいたします。 ちなみに使用しているのは windows7 Visual Studio Express 2012です。

  • クライアント上のC++でサーバーとソケット送信

    クライアント(Windows7)上でC++を使って、サーバー側(Windows)に対してデータを送りたいです (ソケット通信?)。 サーバ受信側はC#を使ったプログラムで以下のような感じで考えてます。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Net; using System.Net.Sockets; using System.IO; namespace ConsoleApplication1 {   class Program   {     static void Main(string[] args)     {       int port = 2222;       System.Net.IPAddress ip = IPAddress.Parse("127.0.0.1");       System.Net.Sockets.TcpListener server = new TcpListener(ip, port);       Console.WriteLine("Enter押してください");       ConsoleKeyInfo info = Console.ReadKey();       if (info.Key == ConsoleKey.Enter)       {         Console.WriteLine("サーバー待機中");         server.Start();         TcpClient client = server.AcceptTcpClient();         NetworkStream ns = client.GetStream();         StreamWriter sw = new StreamWriter(ns);         Console.WriteLine(sw);       }     }   } } C++のことがよくわかってないので、送信側でC++を使ってどのように 送信すればいいのかわかりません。 送信するデータはINT型で、1秒間に1回、繰り返し送ります。 よろしくお願いします。

  • TcpClientとWebbrowser

    TcpClientでストリームからバイトでhttpデータを取得しましたが、 EUC-JPの文字コードのサイトだけがhtml内に本来入るはずのない数値が沢山現れます。 いっそのことWebBrowserコントロールを使ってサイトにアクセスし、DocumentTextを参照した方が手っ取り早いでしょうか? バイトから文字列の変換はわかりましたが、文字列から文字列へ文字コードを変換する方法がわからず困っています。ご存知の方教えていただけますか? 以下、EUC-JPの時に数値が混入するサンプルです。 '--------------------------------------------------------------------------------------------------- ' httpファイルを読み込む '--------------------------------------------------------------------------------------------------- Private Sub GetHttp(ByVal host As String, ByVal port As Integer, ByVal cmd As String, ByRef retcode As Integer, ByRef http_data As String) 'TCP/IP接続を行う Dim client As New TcpClient() Try client.Connect(host, port) 'ストリームを取得する Dim stream As NetworkStream = client.GetStream() Dim param As String = cmd + " HTTP/1.0" + ControlChars.CrLf+ControlChars.CrLf Dim buffer() As Byte = System.Text.Encoding.ASCII.GetBytes(param) stream.Write(buffer, 0, buffer.Length) Dim sb As New System.Text.StringBuilder() Dim len As Integer http_data = "" Dim bytData() As Byte = New Byte(1048576) {} '1MB Dim strCharset As String = "" 'すべて受信する Dim cnt As Integer For cnt = 1 To 1000 '受信 len = stream.Read(bytData, 0, bytData.Length) 'バッファサイズを与えて、受信サイズを得る sb.Append(Encoding.GetEncoding("utf-8").GetString(bytData, 0, len)) 'utf-8 If Not stream.DataAvailable Then '受信キューにデータがある場合はTrue Exit For End If Next '正常に受信できた場合 http_data = sb.ToString retcode = 0 Catch ex As Exception retcode = -1 http_data = "" Finally client.Close() End Try End Sub '----- Dim host As String = "ホスト名" Dim port As Integer = 80 Dim cmd As String = "GET /index.html" '戻り値 Dim retcode As Integer Dim http_data As String = "" Dim charset As String = "" Try GetHttp(host, port, cmd, retcode, http_data) Catch ex As Exception MessageBox.Show(ex.Message, "エラーです。") End Try

  • c# ネットワークプログラム

    c#でネットワークプログラムを作る際、 SocketクラスとTcpListener・TcpClientクラスのどちらで 作るのが良いのでしょうか。 やりたいことは、サーバーとクライアントを接続して送受信させるだけです。

  • winsockを使った通信での同時接続について

    WSAAsyncSelectを使ってソケットにくるネットワークイベントを受け取って処理しようとしています。 サーバーに複数のクライアントが接続してくる通信プログラムを作っています。 クライアントがバラバラのタイミングで接続してくると問題なく通信が行えるのですが 同時に接続してくると通信がうまく行えなくなってしまいます。 サーバー側で接続してくるクライアント分だけソケット作る必要がありますか? lまた、listen関数を使って無いのですが使う必要はありますか?

  • NetworkStreamからのRead()で、処理が止まる(C#)

    C#で、サーバーを作っています。 Readで読み込んで、次に、 Writeで、「ありがとうございました!!」など、 書き出しているのですが、 いままで、それなりに動いたいました。 しかし、クライアント側で、何も書き出さないと、 Read()の部分で、プログラム止まって(待機して) しまっていることが分かりました。 クライアントが、何も書き出さないときは、 さっさと、「ありがとう・・」と書き出して、 終了したいのですが、30秒ほど待機して、 接続が切れてしまうようです(Writeもしない)。 Readは終端-1がくるまで、待機してしまうの だと思います(文字が送られないときは、これが ないので、待機してしまうのかな)。 例えば、送られてくるデータが、もともと無い、 ということを、あらかじめ認識し、 または、5秒くらいで、データが来なければ、 処理を次に移す、といった処理の仕方は、 できないでしょうか。 お願いします。