• ベストアンサー

ソケットのclose

サーバ側のソケットのcloseに関しての質問です。 LISTEN のFDをCLOSEすればACCEPTで発生したFDもなくなるものでしょうか。それとも残ってしまうものでしょうか?

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.1

Acceptで発生したFDであろうとCloseしなければなりませんし、 LISTENしているソケットをCloseしても、 接続が切れるだけで実行されている環境のリソースとしては、 使用されたままになっているはずです。

ritomo
質問者

お礼

回答ありがとうございます。 Listenm,Accept共にcloseするようにします。 ありがとうございました。

関連するQ&A

  • VC6.0ソケット通信プログラムについて

    お世話になります。 VC6.0でソケット通信の社内の既存のプログラムを改善しております。 クライアントより、サーバにソケットで大量に電文を送信した時に、サーバ側の処理が重くなってしまいます。 NETSTATコマンドで確認したところ、 サーバ側では、CLOSE_WAITが大量に出力されており クライアント側では、FIN_WAIT_2が大量に出力されます。 クライアント側のFIN_WAIT_2は、時間が経つと消えるのですが、サーバ側のCLOSE_WAITは残ってしまっております。 サーバ側のEXEを再起動すると、CLOSE_WAITは消えます。 サーバ側のソケットの受信後の処理に問題があるのではと考えておりますが、何処が問題なのかわからない状態です。 コードを以下に記述致します。 WINAPI K010cListener{ /*Winsock初期化*/ WSAStartup(wVersionRequested,&wsaData); /*SOCKET作成*/ fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP) /*ポートの設定*/ addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_family = AF_INET; addr.sin_port = htons(usPortNo); addrlen = sizeof(addr); /*BIND*/ bind(fd,(struct sockaddr*)&addr,addrlen) /*LISTEN*/ listen(fd,0) while(1){ /*ACCEPT*/ fd2 = accept(fd,(struct sockaddr*)&addr,&addrlen) //データ受信 waitReceiveThread(fd2, &rcv_msg); //DBオープン ConnectDB() //DB登録 AddTable(&rcv_msg) //DBクローズ CloseDB() } /*Winsock終了*/ WSACleanup(); } void waitReceiveThread(SOCKET fd, SockRcvMsg *rcv_msg) { while (1) { /*データ受信待ち*/ rcvSize = recv(fd,rcvBuf,sizeof(rcvBuf),0); if (rcvSize <= 0) { continue; } else { /* 返信電文の準備 */ memset(sndBuf,0x20,sizeof(sndBuf)); memcpy(sndBuf ,"RCMORDER00004800000000",22); /* 返信電文の送信 */ send(fd,(char*)sndBuf,sizeof(sndBuf),0); /* バッファの初期化 */ bufsize=0; memset(buf,'\0',sizeof(buf)); break; /*ループを抜ける*/ } } } 恐れ入りますが、ご教授いただければ幸いです。 宜しくお願い申し上げます。

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

    コネクションの確立はlisten関数、accept関数、connect関数を用いて行い、パケット送信の場合は、UDPで送信するというプログラムを作成したいと思っています。 この場合、listen関数、accept関数、connect関数を使用する際は、TCPソケットをオープンするという形になるのでしょうか? それとも、listen,accept,connect関数は、UDPソケットオープンでよいのでしょうか? よろしくお願いします。

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

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

  • ソケットプログラミングとスレッドについて

    TCP/IPソケットを用いた通信プログラムを作成しています。その上でacceptする処理を専用スレッドにしており、accept後の受信処理をまた別のスレッドで処理しています。コンソールプログラムにおいてサーバとクライアントを用意しテストをしてみるとうまくいくのですが、MFCプログラムにおいて同じネットワーク処理を行ってみると、サーバ側へのconnectは成功するのですが、クライアント側からsendしたときにサーバ側でrecvの戻り値が必ず0にしかならず切断された状態になってしまいます。これはどういったときに発生すると考えられるでしょうか?ちなみにMFCが絡んでいるかどうかということは特にわかっておりません。 どなたかこのような経験をお持ちであればご教授お願い致します。

  • ソケット通信異常

    クライアントがソケットを接続した状態でサーバープロセスがいきなりDownした場合、クライアント側でlisten()から抜けてきません。 OSのパッチ等あるのでしょうか?

  • C言語でのソケット通信のclose

    C言語でソケット通信をするプログラムの見本は、大体がサーバのプログラム内でサーバとクライアントのファイルディスクリプタを、クライアントのプログラム内でクライアントのファイルディスクリプタをcloseしてから終了しています。 でも、プログラムを終了させる時にopenしているファイルディスクリプタは自動的にcloseされるのだから、わざわざ明示的にcloseする必要がないと思います。 「明示的にcloseするのがマナーだから」という理由しか、調べても出てきませんでした。 明示的に全てのファイルディスクリプタをcloseする理由をご存知の方、教えてください。

  • ソケット通信におけるデータ送信手法

    ソケット通信ができるサーバプログラムをPHPにて組んでいますが、疑問があります。 Server/Clientの形で、PHPでくんだServer側はListenして通信を待っているのですが、仮に、サーバ側から任意のタイミングで通信を発生させることは可能なのでしょうか。 これが1点です。 あと、1つのサーバプログラムに対して、複数のクライアントが接続するようなパターンは作成可能なのでしょうか。 暗中模索のため、難儀しています。 ご教示いただければ幸いです。

    • ベストアンサー
    • PHP
  • 非ブロッキングソケットのrecvについて

    現在、Winsock2を使ってあるサーバーのプログラムを作成しています。 WSAEventSelect関数を使って非ブロッキングソケットを扱っているのですが、複数のクライアントからほぼ同時に接続要求などがあった際に 接続を取りこぼしてしまいます。 どなたかアドバイスいただけませんでしょうか。 以下、ソースを示します。プログラムの動作をわかりやすくするためエラー処理などは省略して記載します。(実際には行っています) ちなみに非ブロッキングソケットを使用する理由は以下のとおりです。 ・GUIアプリのワーカースレッドで動作させており、ブロッキングソケットでブロック中にメインスレッドが終了してもワーカースレッドがそれを知る術がなくワーカースレッドを安全に終了させることができないため。 /* 変数の宣言*/ int iRet=-1; SOCKET ListenSock; SOCKET AcceptSock; int iRcvClientLen=0; int iRcvLen=0; char caRcvDat[1024]={0}; WSAEVENT hEvent; DWORD dwResult; WSANETWORKEVENTS events; /* リッスンソケットを作成*/ ListenSock = socket(AF_INET, SOCK_STREAM, 0); /* イベントのクリエイト*/ hEvent = WSACreateEvent(); /* リッスンソケットの設定*/ addr.sin_family = AF_INET; addr.sin_port = htons(PORT_NUM); /*PORT_NUMは定数*/ addr.sin_addr.S_un.S_addr = INADDR_ANY; /* リッスンソケットをバインド*/ iRet = bind(ListenSock, (struct sockaddr *)&addr, sizeof(addr)); /* リッスンソケットでポートを開く*/ iRet = listen(ListenSock, 10); /* クライアント接続待ちの無限ループ*/ while (1) { printf("\n\n/--------- 待機中 ---------/\n\n"); iRcvClientLen = sizeof(client); /* リッスンソケットにACCEPTイベントを設定*/ iRet = WSAEventSelect(ListenSock, hEvent, FD_ACCEPT); /* ACCEPTイベント発生まで待機*/ dwResult = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE); /* 発生したイベントを解析*/ iRet = WSAEnumNetworkEvents(ListenSock, hEvent, &events); /* イベント変数をリセット*/ WSAResetEvent(hEvent); /* 発生したイベントがACCEPTであれば接続を受け入れる*/ if(events.lNetworkEvents & FD_ACCEPT){ AcceptSock = accept(ListenSock, (struct sockaddr *)&client, &iRcvClientLen); } /* ACCEPTしたソケットにREADイベントを設定しなおす*/ iRet = WSAEventSelect(AcceptSock, hEvent, FD_READ); /* READイベント発生まで待機*/ dwResult = WSAWaitForMultipleEvents(1, &hEvent, FALSE, WSA_INFINITE, FALSE); /* 発生したイベントを解析*/ iRet = WSAEnumNetworkEvents(AcceptSock, hEvent, &events); /* イベント変数をリセット*/ WSAResetEvent(hEvent); /* 発生したイベントがREADであればデータを読み込む*/ if(events.lNetworkEvents & FD_READ){ iRcvLen=recv(AcceptSock, caRcvDat, 1024, 0); /* ・・・以下Recv後の動作・・・*/ } } おそらく、2回目のWSAWaitForMultipleEvents関数で待機している間に接続要求が来たクライアントを取りこぼしているのだと思いますが、 対処方法がわかりません。

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

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

  • 【ソケット通信】TIME_WAITを0にする方法

    【現状】 VC#でソケット通信のソフトを作成しています。 【問題】 クライアント―サーバ型のソケット通信をしようとしているのですが、切断後すぐに再接続できないという問題が生じております。 【調査結果】 調べたところ、TCP/IPの状態遷移でアクティブクローズ側がTIME_WAIT状態になることが分かっています。TIME_WAITの設定値には意味合いがあり、漂流中の重複パケットの問題を回避するためや最後のACK再送のためであることは理解しております。 【やりたいこと】 今回は基本的に1:1通信でルータを挟まずにやりとりするネットワークなので、TIME_WAITを0、もしくは数msecにしたいと考えています。 ※ 同じIPアドレス、ポート番号で接続したい為(ポート固定での再接続) 【自分で出した解決案の一つ】 どうもサーバ(Listenする側)からアクティブクローズすると、TIME_WAITは生じるもののクライアントから接続要求を出すと同じポートからでももう一度接続できてしまうというのは判明したので、必ずサーバから切断要求を出す仕様にすればTIME_WAITが0になるように思われます。 ただし、なぜ再接続できるのかは不明のため、すっきりしない(&環境や設定が異なると再接続できない可能性あり) 【質問】 (1) クライアント側からアクティブクローズする場合に、TIME_WAIT状態を1秒未満に設定する方法はありますか?(VC#で) (2) サーバからアクティブクローズした場合に、なぜ再接続できてしまうのでしょうか? 以上の2点の質問に、どうかご回答のほどよろしくお願いいたします。

専門家に質問してみよう