• ベストアンサー

ソケット通信で、250本しか接続できない

solaris上で、ソケット通信をするプログラムを作成しております。 サーバー側にクライアントを多数接続したいのですが、 250本くらい接続するとサーバー側でacceptを呼び出したタイミングで セグメント例外を出力して異常終了してしまいます。 ここからは推測なのですが、 サーバー側のディスクリプタが255までは正常に動作するため、 ディスクリプタの数が256に制限されているのではないかと思います。 そこで、ulimitでdescriptorsを増やしたり、 setrlimit関数で、RLIMIT_NOFILE値を増やしたりしてみましたが、 状況は全く変わりませんでした。 念のためスタックサイズを増やしてもみましたがやはり効果ありませんでした。 どなたか、解決方法をご存じでしたら、ご教授頂けませんか? よろしくお願いします。

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

  • ベストアンサー
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.6

fort-cは現在sun studioに統合されたようです。 無償で評価版はダウンロードできますので、 gccで解決出来ないときは、こちらを試されては如何でしょうか。 参考URLからダウンロードできます。

参考URL:
http://jp.sun.com/products/software/tools/studio/
uu0v0uu
質問者

お礼

いろいろありがとうございました。 スレッドが古くなってしまったので閉じさせて頂きます。 あとは自分でなんとかやってみようと思います。

その他の回答 (5)

  • g_vikke
  • ベストアンサー率16% (15/90)
回答No.5

FDより、プロセス数とかスレッド数とか関係してそうですね。acceptして、作るんでしょ? どこで死んでるかだけですけどね。

uu0v0uu
質問者

お礼

せっかく回答頂いたのですが、 シングルスレッドで作成していて、 acceptしてもプロセスもスレッドも増加しておりませんので、 その辺は大丈夫かと思います。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

>となると環境の違いか、もしくは別の値の制限を受けてしまっているのでしょうか。 >差し支えなければ、tatsu99さんの試した環境を教えて頂けますでしょうか? solaris8(sparc)でfort-cでコンパイルしました。 gccは使用していません。 私が確認したときは、getrlimitで取得した結果が、ソフトリミット=256、ハードリミット=1024でした。 ソフトリミット=300にして、約300迄の接続を確認しました。使用されているOSはインテル版でしょうか? 当方はSPARC版で64ビットモードでコンパイルしています。 うーむ。環境の違いか、別の値の制約・・・ 問題は、それが何なのかですね。・・・役に立てなくて申し訳ない。

uu0v0uu
質問者

お礼

ありがとうございます。 こちらもSPARC版ですが32ビットモードです。 コンパイラも違うみたいですし、そのあたりが怪しいですね。 なんとかしてその辺も変えてやってみようと思います。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.3

>setrlimit関数で、RLIMIT_NOFILE値を増やしたりしてみましたが 当方で確認しましたところ、setrlimit関数でソフトリミットを増やしたところ、256を越える接続に成功しました。 従って、アプローチとしては、この方法で良いかと思います。 getrlimitで、現在のリソースを取得し、そのソフトリミットを、setrlimitで更新しました。 ソフトリミットを増加させる前は、acceptのエラーは、errno=24(EMFILE:Too many open files )が返ります。 セグメンテーションエラーは、発生しません。 まず、#1のかたが言われているように、セグメント例外を出力して異常終了するのを修正するのが、先かと思い ます。それが、解決すれば、同時オープンソケット数の拡張は、可能かと思います。 acceptでセグメンテーションエラーが起こるとすると、 第3パラメータのaddrlen(第2パラメータのサイズ)が、正しくない可能性があります。これは、IN/OUTのパラメータなので、毎回、正しく設定し直してから、呼び出す必要があります。その点は、確認されましたでしょうか。 話題は、変わりますが、1プロセスで256以上のソケットを作成し、接続する必要があるのでしょうか? もし、256以上の接続ができても、パフォーマンスの観点から、実用に耐えるかどうかが疑問です。この点は問題ないのでしょうか。

uu0v0uu
質問者

お礼

ありがとうございます。 方向はあっているとのことなので、もう少し頑張ってみます。 下の欄にも書きましたが、セグメント例外に関してはミスでした。 acceptはおっしゃるように Too many open files のエラーが返るようです。 > getrlimitで、現在のリソースを取得し、そのソフトリミットを、setrlimitで更新しました。 同様にしてやってみました。 getrlimitで変更後の値も確認しましたが、それでもToo many open files のエラーが発生します。 逆にソフトリミットの値を減少させると、接続できる数が減るため、値の変更はできているようです。 となると環境の違いか、もしくは別の値の制限を受けてしまっているのでしょうか。 こちらの環境は、solaris8でコンパイラはgccの2.95.3です。 差し支えなければ、tatsu99さんの試した環境を教えて頂けますでしょうか? パフォーマンスまで心配して頂いてありがとうございます。 もちろん動かしてみないとはっきりしたことはわからないのですが、一応動作するように作っているつもりです。

  • ponshige
  • ベストアンサー率40% (12/30)
回答No.2

/etc/systemファイルで次のパラメータを設定することでシステムでの制限を変更することができます。 rlim_fd_max ハードリミット rlim_fd_cur ソフトリミット 設定例) set rlim_fd_max=0x10000 ただし、この拡張はあくまで64ビット環境だけですので、同じシステムを32ビット環境にしたり64ビット環境にするような場合は/etc/systemファイルでの設定は危険です。 またselect()を使用するユーザアプリケーションをコンパイルする際にFD_SETSIZEマクロを定義することでselect()が扱うことのできる記述子の再設定が可能になっています。 sun% cc -DFD_SETSIZE=4096 .... ・fopen(3C)で開くことのできるファイル数 とありましたが、これではダメですかね? 実際に自分でやったわけではなく申し訳ないですが。。 手元のUNIXネットワークプログラミングの本では <sys/types.h>ヘッダ(<sys/select.h>かも?)の #define FD_SETSIZE 256 となっているものを変更したあと、カーネルの再コンパイルが 必要なようです。

参考URL:
http://www.nsug.or.jp/readme/no30/FA30.html
uu0v0uu
質問者

お礼

ありがとうございます。 /etc/systemはいじってみましたが、だめでした。 rlim_fd_max ハードリミット rlim_fd_cur ソフトリミット これらの値を設定し、リブートしてみました。 確かにlimitで確認できる数値に変化はあるのですが、 なぜか動作させた時に256で制限を受ける状況は変わりませんでした。 FD_SETSIZEもデフォルト1024でした。 念のため、-DFD_SETSIZE=1024と明示的に指定してみましたがそれでもうまくいきませんでした。 なかなかうまくいかないものですが、自分でもいろいろ試してみます。 URLありがとうございました、とても参考になりました。

  • coredump
  • ベストアンサー率46% (12/26)
回答No.1

solarisは使った事無いのですが、一般的に OSの制限にひっかかってセグメント例外を出すって のは考えにくいです。 プログラム上のミスが原因である可能性が高いと 思います。 僕だったら、デバッガでacceptの引数のポインタが 正常な値かのチェックとか、最小限のコードを書いて テストしますね。

uu0v0uu
質問者

お礼

ありがとうございます。 セグメント例外はミスでした。 ディスクリプタが足りなくなって、acceptがエラーで返ってきたのをファイルに吐こうとして、 ファイルをオープンする部分でやっぱりディスクリプタが足りないので、 ファイルがオープンできなかった、というエラーをさらにファイルに・・・・ というループにハマってました。

関連するQ&A

  • JAVAのソケット通信の接続数について

    JAVAのソケット通信の接続数について ServerSocket server= new ServerSocket( port ); server.setSoTimeout( 4000 ); Socket socket = server.accept();//クライアントからの接続をまつ 以上のコードを使っていますが、クライアントからの接続数を調べる方法はないでしょうか?

    • ベストアンサー
    • Java
  • ソケット通信での再接続

    ソケット通信での再接続 ソケット通信でサーバ側は立ち上げたまま、 クライアント側を同じポート番号で 何度も再接続できるようにしたいと考えております。 http://blog.livedoor.jp/akf0/archives/51585502.html を参考にマルチスレッドを利用してプログラムを作成してみましたが 最初の起動に関してはうまくいくのですが、 クライアント側を一度終了してもう一度再接続すると、 バインドエラーが出ます。 いろいろ試してみたのですが、 どうしてもうまくいきません。 どうすればいいのでしょうか。 ご存じの方がいらっしゃればお答えいただきたいと思っております。 よろしくお願いいたします。 環境 OS:Windows XP 開発環境:Visual Studio 2008 Express Edition ソケット通信:winsock2 マルチスレッド:win32api

  • ソケット通信で接続クライアントの上限を設ける

    (Unix c言語) ソケット通信で、サーバに接続するクラインとの上限をきめてそれ以上の数の接続要求があった場合、そのクライアントに対しての接続を拒否するには、サーバ側とクライアント側でどのような書き方をすればいいでしょうか?

  • C#でソケット通信

    初歩的な質問ですみません。 クラアント側とサーバー側にそれぞれC#で作ったプログラムをインストールし、 クライアントからサーバーにデータを繰り返し送信したいとき、 そのプログラム内でソケット接続して送ることはできるでしょうか? できるとして、どのような手順でソケット接続し、データを送ればいいのでしょうか? まったくの初心者です。 よろしくお願いします。

  • vb2010でソケット通信を使いたいのですが

    はじめまして。 vb2010でソケット通信を使いたくて、今TCPサーバーを作っています。 クライアント側から受信した瞬間にサーバー側から返信というのは可能でしょうか。 受信したタイミングで接続が切れてしまって困っています。 初めてソケット通信に触れてイマイチ分かってないので説明がうまくいきませんが、 どなたかわかる方がいらっしゃいましたらご回答よろしくお願いします。

  • ソケット通信異常

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

  • ソケット通信(サーバ側)について

    環境:Windows2000とWindows2000(サーバに見立てて) WinScok2にてサーバソケットAPを作ったのですが、 クライアントからの接続でタイムアウトエラーになります。 以前にPC側APとサーバAPでポートが同じでなければいけないと言われ修正したのですが、まだ接続できません。 以前の方にも言われたのですが、サーバAPを起動後にプロンプトからtelnet (リスンされたIP) (ポート番号)で起動すると、接続に失敗しました。とメッセージが表示されます。 サーバAPはaccept()で待っている状態です。 何か洩れている箇所があるのでしょか?

  • ソケット通信について

    VC++6.0MFCでソケット通信のプログラムを作成しようとしています。勉強始めたばかりなので、やっと普通に通信するプログラムは理解できたところです。 そこで応用していろいろ考えているのですが、方法がわからないところがありますので教えていただければと思ってます。 サーバ側の接続待ちはいつでも受けれるようにして、接続してきたクライアントに対して送信したいと考えております。ソケットの接続情報を保持しておいて、別プロセスの送信プログラムが接続クライアントに対して送信したいと考えてます。その送信プログラムが複数ある場合も同じ接続情報を利用したいと考えてるのですが、可能でしょうか。 説明が下手で申し訳ありません。補足はいたしますので、アドバイスお願いいたします。

  • ソケット通信で同時受信の制限?

    こんにちは。 早速ですが、ソケット通信について質問です。 複数クライアント(Win)からサーバ(UNIX)に対して、connect()し、サーバ側はaccept()したら、それぞれに対しfork()で子プロセスを作っています。 そこで、50台くらいのクライアントから一気にconnect()すると通信エラーとなってしまうのですが、なにか制限があるのでしょうか? connect()のタイミングをずらせば、それぞれのクライアントとサーバの子プロセスでやり取りができます。 一斉にconnect()される場合の通信エラーの原因や対処法などをご教授願います。 初歩的なことかもしれませんが・・・。 よろしくお願いいたします。

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

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

専門家に質問してみよう