• ベストアンサー

ソケットのクローズについて

SOCKETのCLOSE直後のOPENが正しく動作しません。お力をお貸しください。 環境:WinXP 言語:C 事象:1回目はうまく動作しますが、2回目以降のOPEN処理がエラーとなってしまう。 しばらく待つ(15秒ほど)と正しくOPENされます。 CLOSEとOPENのどちらに問題があるのでしょうか? SOCKETのCLOSEに多少時間がかかるものなのでしょうか?またその時間はどれくらいなのでしょうか? 宜しくお願い致します。 ※CLOSE:closesocket関数 shutdown関数を使用

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

  • ベストアンサー
  • furlong
  • ベストアンサー率50% (17/34)
回答No.2

開くとき、socketの後のbindでエラーになっていませんか。もしそうなら、そういうものです。ソケットを閉じた後、ポート番号が解放されるまでに時間がかかります。WinSockは詳しくありませんが、普通のOSでは2分ぐらいかかる場合もあります。 対策としては、クライアント側ならポート番号のbindを止める。サーバーなら親ソケットを開いたままにしてlisten/acceptを使う。

その他の回答 (3)

  • e101tre
  • ベストアンサー率38% (7/18)
回答No.4

socket() でオープンしたソケット記述子に対して、SO_REUSEADDR 属性を設定してみては? (例) int isock, ist, iopt; isock = socket(…); iopt = 1; ist = setsockopt(isock, SOL_SOCKET, SO_REUSEADDR, (char *)&iopt, sizeof(iopt));

  • ShaneOMac
  • ベストアンサー率39% (356/898)
回答No.3

ShutDownを入れるところに問題があるのでは?これではプロトコルがなんなのか、サーバーなのか、クライアントなのか、どういったレベルのソケットを作成しているのかなど分からないところが多いのですが。そもそもOPENとは? 下のはCAsyncSocket::ShutDownの解説ですが、同じです。 > ShutDown はソケットを閉じません。また、Close が呼び出されるまでソケットに結び付けられたリソースも解放しません。アプリケーションは、シャットダウンした後のソケットを再使用できるからといって、それを利用しないでください。特に、Windows ソケットのインプリメントは、そのようなソケットでの Connect はサポートしていません。 >

  • rara_sun
  • ベストアンサー率50% (271/539)
回答No.1

プログラミングに関する知識はないので、余り参考にならないかもしれませんが・・。 当たり前ジャンと怒られそうなのですが、 記載されていなかったので確認ベースで・・。 closesocket()の実行前に、shutdown()を実行してるんですよね? あ~、絶対に怒られる・・。ご容赦を・・m(__)mペコ この辺は、プロトコルのお約束ですものね。失礼しました。

関連するQ&A

  • ソケット通信のオープンクローズ

    MFC、VC6(WINXP)の環境でソケットプログラムを作成しています。 オープン処理として  (1)ソケットの作成  (2)ノンブロッキングに変更  (3)タイムアウトを設定  (4)コネクト  (5)セレクト クローズ処理として  (1)シャットダウン  (2)クローズソケット サーバーはアドレスが二つあり(2プログラム)とちらかが起動していなかったらもう一方のアドレスに接続する為、電文の送受信毎にオープン処理とクローズ処理を繰り返しています。 質問  (1)数百回オープンクローズを処理しているとオープン出来ない時があります。何故でしょうか?  (2)指定したアドレスにサーバーソフトが立ち上がっていなかった時に コネクトのタイムアウトに時間がかかっているのでノンブロックに変更 しましたが間違いでしょうか?ブロッキングで対応できますか?  VC初心者なので宜しくお願いします   

  • SocketのSend関数でのCLOSEの検知 [Linux]

    Linux環境でSocket(dm:PF_INET,type:SOCK_STREAM)を使用しての、 Client&ServerプログラムをCで作成しているのですが、 そこでのSend関数の使い方についてご助力ください。 Client&Serverプログラムは下記のような動きをします。 [Client] ServerへConnectした後、複数のDataを数秒間隔でServerへ 送信(send関数使用)します。受信(recvやread関数等)は、 一切行いません。 [Server] ClientからのConnectを受け付けた後、Clientから受信(recv関数 使用)したDataを標準出力へ表示する。送信(sendやwrite関数 等)は、一切行いません。 さて、ここでもしClientプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Server側のSocketが CLOSE_WAIT状態になった場合、Bufferに溜まっていたDataを すべて受けきった後、recv関数が0を返してくれるので 相手が終了したことがわかります。 ここからが質問のMainです。 では、もしServerプログラムがCloseを発行したり、マシン DOWN等の理由でConnectionが切断され、Client側のSocketが CLOSE_WAIT状態になっても、CLOSE_WAIT直後のsend関数が なぜか正常に処理されてしまいます。無論このDataは、 Server側は受け取りません。この次のsend関数実行時に EPIPEが返ってくるので、ここでようやくSocketが切断された ことが判ります。 これを何とかCLOSE_WAIT状態になった直後から、send関数で 切断を検知できるようにできないでしょうか。 よろしくお願いします。 以上

  • ソケットを閉じる操作が・・・

    こんばんわ。 winsockを用いてC言語によるソケットプログラミングを行なってます。 ソケットを(SOCKET s1,s2)用いているのですが、両者はローカルで指定しています。しかし、私のプログラミングの記述の仕方が悪く・・・ もし、エラーが発生した場合、s1はクローズできる仕様なのですが・・・s2をクローズできないプログラムになってしまいました。 エラーが発生時、プログラム自体を終了する・・とした場合、ソケットはクローズされるのでしょうか? また、テキストには必ずソケットをオープンした場合クローズする必要があると書いてあるのですが、どういう意味でしょうか? ローカルからグローバル変数へ変更すれば解決できるのですが、グローバル変数へ変更しても大丈夫でしょうか? よろしくお願い致します。

  • ソケットプログラミングについて

    こんにちは。 前回、質問しました「バード」という者です。 ソケットプログラミングについて質問します。 PC1から、jpegやmpegファイルを送信しPC2で受信するというプログラムをC言語で作ってみたいと思っています。 以前、少しだけJAVAプログラミングでPC1(送信側)からPC2(受信側)へデータを送信するプログラムを作ったのですが、作ったプログラムの概要を以下に示します。 [送信側] (ファイルオープン) InputStream in = new FileInputStream(ss); BufferedInputStream bin = new BufferedInputStream(in); ↓ (データを読みsendメソッドにて随時送信) while((c = bin.read(buffer, 0, buffer.length))!=-1){ dPacket = new DatagramPacket(buffer,buffer.length,iAddress,port); dSocket.send(dPacket); } ↓ (ファイルとソケットクローズ) dSocket.close(); [受信側] (ファイルオープン) OutputStream out = new FileOutputStream(args[1]); BufferedOutputStream bout = new BufferedOutputStream(out); ↓ (送信側から来たデータをreceiveメソッドにて受信) while(true){ dPacket = new DatagramPacket(buffer,buffer.length); dSocket.receive(dPacket); } ↓ (ファイルとソケットクローズ) dSocket.close(); 上記に示す様に、ファイルをオープンし、DatagramSocketとDatagramPacketクラスを用いて送受信し最後に、ファイルをクローズするという形式をとっていました。 C言語の場合でも、ファイルオープン→send関数,receive関数等を用いて送信・受信→ファイルクローズという形をとる事ができるのでしょうか?FTPプログラムやエコープログラムを、よく見かけるのですが・・・・

  • ファイルopenエラーになってしまう。

    はじめまして。 今、open関数を使用してファイルをオープン(3秒に1回)しているのですが、一定周期でエラーになってしまいます。  周期:2時間7分 このファイルにIOをかけるのは、ここだけでcloseもちゃんとあります。openのリトライは3回(sleep(300))です。原因が全くわかりません。 どうか、宜しくお願いします。 (win2000 VC6.0)

  • ソケットにおけるメッセージの送受信について

    いつもお世話になっています。 ソケットに関して質問します。 下記の手順でソケットを使用したいと考えています。 クラスAとクラスBが存在する。 1)クラスA:ソケット通信でメッセージ送信 2)クラスB:ソケット通信によるメッセージを取得 3)クラスB:ソケット通信で返信する 4)クラスA:ソケットによるメッセージを再取得する このとき、クラスAがクラスBによるメッセージ再信が、30秒以内にこなければ、ソケットを閉じる それにあたってソースを1クラスで実行できるよう書き変えたいのですが、どうも上手くいきません。 実行したいメソッド手順が ソケットを開く openSocket ソケットにメッセージ送信 sendMsg ・・・1と3はこのメソッドを使用 メッセージ取得 getMsg ・・・2と4はこのメソッドを使用 ソケットを閉じる closeSocket の順です。 自分で一度考えてみたソースは以下です。 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; public class Messaneger{ private Socket socket; private BufferedReader in; // ソケットを開く public void openSocket() { ServerSocket serverSocket; try { serverSocket = new ServerSocket(5555); System.out.println("クライアントからの接続をポート5555で待ちます"); // クライアントからの接続を待ちます Socket socket = serverSocket.accept(); System.out.println(socket.getInetAddress() + "から接続を受付ました"); // 出力ストリームを取得 PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); } catch (IOException e) {} } //ソケットを閉じる public void closeSocket() { try { socket.close(); } catch (IOException e) {} } /** * ソケット通信でメッセージを送信 * @param 送信するメッセージ */ public void setMsg(String sendMsg) { try { socket = new Socket("localhost", 5555); PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // 入力ストリームを取得 in = new BufferedReader( new InputStreamReader( socket.getInputStream())); //サーバーにメッセージ送信 out.println( sendMsg ); //送信メッセージdata System.out.println(sendMsg); } catch (IOException e) {} } /** * ソケット通信でメッセージを取得 * @return msg サーバーに渡されたメッセージ */ public String getMsg() { String getMsg = ""; BufferedReader in; try { in = new BufferedReader( new InputStreamReader( socket.getInputStream())); System.out.println(in.readLine()); } catch (IOException e) {} return getMsg; } } 参考URL:http://www.hellohiro.com/socket.htm 宜しくお願いします。

  • JavaのTCPソケット通信プログラムについて

    初めてJavaでTCPソケット通信を書いてみたのですが、質問です。ソケット通信をサーバーとクライアント側で確立した後、メッセージの送受信をやるとても簡素なプログラムを作成しました。一回目の送受信をするだけだと上手くいくのですが、同じコネクション内で二回目の送受信をするよう追記したところ動作がおかしくなりました。(一つ目のメッセージも受信しないまま画面が停止した状態になる)何が問題なのでしょうか。 (Receiver.java) public class Receiver { public static final int PORT = 30000; public static void main(String[] args) { try { ServerSocket serverSoc = new ServerSocket(PORT); Socket socket = null; System.out.println("Waiting for Connection.."); socket = serverSoc.accept(); System.out.println("Connection from "+socket.getInetAddress()); // receive message BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("Message from sender ="+new String(br.readLine())); //send message←ここを追記するとおかしくなりました。 String message = "Hey This is receiver"; BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); System.out.println("I will send: "+message); bw.write(message); br.close(); bw.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } } (Sender.java) public class Sender { public static final int PORT = 30000; public static void main(String[] args) { try { InetAddress LocalHost = InetAddress.getLocalHost(); InetSocketAddress socketAddress = new InetSocketAddress(LocalHost, PORT); Socket socket = new Socket(); socket.connect(socketAddress, 10000); //send message String message = "Hey This is sender"; BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); System.out.println("I will send: "+message); bw.write(message); // receive message←同じくここを追記するとおかしくなりました。 BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); System.out.println("Message from receiver ="+new String(br.readLine())); br.close(); bw.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }

  • ソケット通信処理について

    現在、下記のようなクライアント、サーバ通信を行っております。 [クライアント] (a)WSAStartup (b)socket (c)connect (d)send(サーバへの要求送信) (e)recv(サーバからの応答受信) (f)shutdown (g)closesocket (1)プロセスは、常駐している (2)(a)は初回起動時1回のみ (3)通常(d)~(e)を周期的に行う (4)(e)にて一定時間経過した場合、5秒待ち6回リトライし、それでもだめな場合は、(f)(g)を実施後(b)から処理を行う。この後、WSACleanupを行っていない。プロセス終了(exit)もしていない。 [サーバ] (a)socket (b)bind (c)listen (d)accept (e)子プロセス生成 以下子プロセス処理 (f)select (g)recv(クライアントからの要求受信) (h)send(クライアントへの応答送信) (1)親プロセス((a)~(e)を行うプロセス)は常駐している。子プロセス起動後、(d)でconnect待ちとなる。(クライアント側からの再接続待ち) (2)子プロセスは、通常(f)~(h)の処理を行い、(f)又は(g)の異常時にexitする。 この処理で、クライアント処理(e)の一定時間経過後の再接続が正常に動作しない場合があります。 詳細情報を取得していませんが(現実的にすぐに詳細情報を取得することができない状況)(c)にて異常が発生していると思われます。 一度その状態になると二度と再接続できなくなり、マシン再起動(プロセス再起動)で復旧させることになります。 (実際は、マシン再起動後に再接続が正常になることを確認しています。(プロセス単体の再起動での確認はしていません。)) そこで質問ですが、 (1)再接続時、WSACleanupを行っていないが、問題ないか(処理の順番:(f)→(g)→(b)) (2)再接続前にプロセス終了(exit)していないが、問題ないか (3)上記の作りで考えられる要因として、何があるか ご教示して頂きたく、宜しくお願い致します。

  • 自動実行について

    こんばんは。 大変お世話になっております。 Visual C++.NETを用いてコンソール上でwinsockでソケットプログラミングを行っています。言語はC言語とWIN32APIを用いています。以下に示す動作を複数回、自動実行?というのでしょうか・・・は可能でしょうか? 1.ファイルオープンとメイン内でスレッドAとスレッドBを生成(マルチスレッド)です。この際、スレッドAでソケット1オープンし、スレッドBでソケット2をオープンしています 2.ファイルに取得値を書き込み 3.スレッドAとB内でソケットクローズ 4.メイン内でファイルクローズとCloseHandle関数にてスレッドA・B終了 1~4の内容を自動実行させたいのですが、なにか方法はあるのでしょうか?バッチファイルをあてると聞いたことがあるのですが、作り方が分からないのでお聞きしたしだいです。 よろしくお願い致します。

  • タイマースイッチという機械で照明を動作させたい

    今、タイマースイッチという機械で玄関などの照明を動作させたいと考えております。それで、”タイマースイッチ”というキーワードでググってみたところ オムロン社製マイクロタイマ   H3M http://www.fa.omron.co.jp/products/family/195/download/catalog.html このような機会が出てきました。 それで、この製品では次のような動作が可能かどうかご教授いただけませんでしょうか? *基本的に入力はクローズ検知で、出力はNO(ノーマリーオープン)とさせていただきます。 1.入力側が10秒間 閉(Close)状態だったら、そこからタイマーを起動し、30秒後に出力を閉(クローズ)にする。 2.入力側が10秒間 閉(Close)でなかったならば、無視する 3.入力側が閉(Close)→開(open)で10秒間 開(open)状態だったら、そこからタイマーを起動し、30秒後に出力を開(open)にする。 4.入力側が10秒間 開(open)でなかったならば、無視する オムロン社製マイクロタイマ   H3M このような動作をこの製品にさせることができるのか ご教授いただきますよう、よろしくお願いいたします。

専門家に質問してみよう