TCPポートの自動選択について – プログラミング – Home

TCPポートの自動選択について
 
通知
すべてクリア

TCPポートの自動選択について

固定ページ 1 / 2

るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

お世話になります。
TCP通信処理をコーディングしていて疑問に思ったので質問させていただきます。内容的
にはC++から少し外れるかもなのですが。

1対多の通信でサーバ側は特定のポートで待ち受けをしており、クライアントからのコネ
クト要求によってOSが任意のポートに割り振りをしてサーバクライアント間でコネクショ
ンが確立します。200クライアント程接続したとき、サーバ側で他のアプリケーション
が使用したいポートがクライアントとの接続に使用されてしまいました。

このような重複はどうすれば回避できるのでしょうか。PGで自動割り当ての範囲を指定、
なんてのは無いですよね?。思ったのは、SERVICESファイルに定義されたポートは自動割
り当てから除外される?なのかなぁというところですが、割り当てされない、という検証
も確実にできないので。

以上、よろしくお願いします。


引用解決済
トピックタグ
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

unixやlinuxでは設定で自動で使える範囲を一つ指定できる
複数の範囲を指定できるOSもある
Windowsはどこにその定義があるのか知らない
いろんなポートが使われているから難しいよね


返信引用
とり
 とり
(@とり)
ゲスト
結合: 22年前
投稿: 23
 

たしかbind()を使うと固定(指定)出来た気がします。
自信がないので確認してみて下さい。

「bind socket」
http://www.google.co.jp/search?q=bind%E3%80%80socket&sourceid=navclient-ff&ie=UTF-8&rlz=1B3GGGL_jaJP282JP282&aq=t


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

wclrp様、とり様
早速のご回答、ありがとうございます。

確かにbind関数でポートは指定できますよね。私もINADDR_ANYしか指定したこと無いので
すが(^^;。
10個程度のクライアント端末であれば個別にポートを定義しておいて指定するのは問題な
いのですが、200程度ともなると大変な為、基本はOSにあいているポートを自動選択させ
たいと考えています。でも、自動割り当てされると困るポートがあるわけで・・・。なん
かないのかなぁ・・・。


返信引用
dogatana
 dogatana
(@dogatana)
ゲスト
結合: 16年前
投稿: 4
 

強引ですが、使用予定で、OSに割り当てされては困るポート番号を well-known
ポートから選択するというのはどうでしょうか?
もちろんシステムで使用できるかどうかの確認、条件設定が必要になります。

ただ、一般にはサーバが待ち受けに使用するポートをbindで指定し、その後
acceptで接続待ちになると思うのですが、その後OSが自動当てするポートと
いうのは何なのでしようか。参考までに教えていただけますか。

サーバ側は全てのクライントに対し、同じ番号のポートを使用する思ってい
ました。プログラムはacceptが返すソケットを使うだけで、待ち受けの
ポートと別のポートが割りあたるかどうか気にしたことがありません。^^;


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

サーバー側TCP/IPソケットではアドレスにバインドされたソケットを使います。
サーバー側ではこのソケットをlistenしており、このソケットにconnectしてきた
クライアントに対してacceptします。acceptするたびに異なったint値が戻ります
(一般にアクセプトソケットと言います)。
一般にはこのアクセプトされたソケットがサーバー側の送受信ソケットに
なるわけです。

従って、一般的なサーバーコードにおいては、ご懸念の事態は発生しません。

サーバーコードはクライアントコードとは全くことなるものであることを
確認するため、一度書いてみることをお勧めします。


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

dogatana 様、仲澤様
>ALL

お世話になります。

申し訳ありません。現在出張中で仕事の合間に書き込みしていたものですから、少し考え
がまとまっていない状態で間違った内容を書いてしまいました。

試験として、クライアント端末からサーバ端末に200個のTCPコネクトを行いました。
クライアント側はポートを自動選択にさせています。その結果、任意200個のポートがク
ライアントソケット用として使用されますが、その後に起動するアプリが使用するサーバ
ポートとかぶってしまいました。

上記内容であってると思うのですが ^^;;;。
自前のアプリが使用する予定であるポートをリザーブしておきたいというのが質問の趣旨
です。
well-knownポートはできれば使用したく無いかなぁと思います。気持ちだけの問題かもし
れませんが、皆さんはどうでしょうか。

以上、よろしくお願いします。


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> 上記内容であってると思うのですが ^^;;;。
あっていると思いますね。

> 自前のアプリが使用する予定であるポートをリザーブしておきたいというのが質問の
> 趣旨です。
 たぶんOSで設定しないと無理だと思います。
普通のWIN XP(プロフェッショナル版ですが)見当たりませんね。
「サーバーOS」か、もしくは「専用のソフト」が必要かも知れませんね。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

ポート番号xxxxに対しconnectしたクライアント側で
「netstat -a」コマンドで調べてみたら

TCP (クライアント):nnnn (サーバーIP):xxxx  ESTABLISHED

ってな感じで、クライアント側のポート番号は、
サーバー側でListen用のソケットのポート番号とは無関係のポート番号ですね

acceptするとソケットが作られるとしか意識してなかった


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

そゆことでしたか。完全に読み間違ってました。
役に立たなくてすみません。

リザーブはできそうに無いので、サーバーアプリ側が
オンデマンドでポート番号を供給する仕組みを考えるとかかなぁ
・・・う~む(vv;)。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

1対多でつなぐとしても
クライアントPC1台につき、クライアントソフトは1つもしくは少量ではないのでしょう
か?

PC一台につき1ソフトなら、自動割当せず、固定ポート番号でやればいいし
複数だとしても、使用したいポート番号の最小値、最大値あたりを決め

/********************************************/
port = 最小値-1;

while( !ret && port < 最大値 ){
port++;
ret = /* portで接続用ソケットを作成 */;//使用されてりゃ失敗
}

/*ここでサーバーにコネクト*/

/********************************************/

こんな感じで、使用したいport番号をズラしながら接続していくのはどうでしょう?


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

お世話になります。ご回答、ありがとうございます。

ITO様
>たぶんOSで設定しないと無理だと思います。
私もやるとすればOS側かなぁと思っています。SERVICESファイルに書いたものがリザーブ
されないかなぁと思っていたのですが、やはり名前参照の為だけのものなんでしょうか。

以下はSERVICESファイルの中の一行ですが

ms-sql-s 1433/tcp #Microsoft-SQL-Server

上記の定義であれば1433は自動割り当てされることはない、というのが理想ですが。
            ~~~~~~~~~~~~
週末になれば試験ができるので、だめもとでやってみようかと思います。

仲澤様
こちらこそ、間違った情報で混乱させてしまいました。すいませんでした。
自身が管理していない他の通信アプリがポート自動割り当てにより、自身の使用予定であ
るポートを使ってしまう、ということが防げればいいなぁと思っています。他のアプリが
サーバポートに使ってしまうようなケースは初期の環境作成の段階で発生しないように考
慮するべきことと思いますので。
自身で管理していない他のアプリに対しては、ポート情報を伝えるような手段はないなぁ
というところです。

rin様

>1対多でつなぐとしても
>クライアントPC1台につき、クライアントソフトは1つもしくは少量ではないのでし

実際には多対多通信・・・といいますか・・・。
全ての装置で同一のポートでListenしています。

装置A           装置B
Listen(2000) ←-------- コネクト  
 コネクト  --------→ Listen(2000)  

上記のように2装置間で見れば2本の通信パスを持つことになります。
これが200~300装置程度に拡大したところを想像していただければ・・・。

実際、業務でどのように使うかは別として、このような相互接続する通信の仕組みを作っ
た場合に、ポートを大量に使用するので、その他の業務アプリが使用する予定のポートと
かぶらないようにしたいなぁと思った次第です。

>複数だとしても、使用したいポート番号の最小値、最大値あたりを決め
なるほど。この方法は使えそうですね。使用するポート番号の範囲を定義ファイル化して
おけばいいだけですし、通信アプリ側も軽微な修正でいけそうですね。試してみたいと思
います。


返信引用
dogatana
 dogatana
(@dogatana)
ゲスト
結合: 16年前
投稿: 4
 

Windowsの場合、1000番台(1024からだでしょうか)から割り当てられる模様
で、2000とかだと使用状況によって、クライアント側がサーバに接続する際のポート
に割り当てられてしまうかもしれませんね。
ただこれはWindowsの場合で、組み込み用の某RTOSだと65000番台から小さくなる方
向に自動割付してました。

サーバが使用するポート番号について、身近のアプリ(特殊用途向け)を調べてみました
が、5000番台と大きな番号でした。もちろん、設定で変更できます。
このあたりだと両方から攻められても実用上は問題ないかと。

試してませんが、Windowsではレジストリに登録して予約ができる模様。
http://www.microsoft.com/japan/technet/community/columns/cableguy/cg1205.mspx


返信引用
ITO
 ITO
(@ITO)
ゲスト
結合: 22年前
投稿: 1235
 

> 私もやるとすればOS側かなぁと思っています。SERVICESファイルに書いたものが
> リザーブされないかなぁと思っていたのですが、やはり名前参照の為だけのもの
> なんでしょうか。
> 以下はSERVICESファイルの中の一行ですが
> ms-sql-s 1433/tcp #Microsoft-SQL-Server

これは、システム予約ですね。
メールの送受信、FTP送受信等ウインドウが標準で使うポートの定義ですね。
るしさんが示した例は、
 「ms-sql-s」というウインドウ標準サービスで使用するポート「1433」という
ことになると思います。
つまり、「1433」というポートは、
   「ms-sql-s」というサービスで使う。
ということになります。


返信引用
るし
 るし
(@るし)
ゲスト
結合: 16年前
投稿: 19
Topic starter  

お世話になります。

servicesファイルへの定義でポートを予約できるか試験してみました。

以下のようにservicesファイルに自分の予約したポートを定義します。

myapp 52300/tcp #My App

その後、この端末で300個のサーバーポートを開き、他の端末から300個
の接続を行ってみたところ、netstatの表示結果が以下のようになりました。

TCP home31:3125 192.168.3.2:52298 ESTABLISHED
TCP home31:3126 192.168.3.2:52299 ESTABLISHED
TCP home31:3127 192.168.3.2:myapp ESTABLISHED
TCP home31:3128 192.168.3.2:52301 ESTABLISHED
TCP home31:3129 192.168.3.2:52302 ESTABLISHED

やはり、servicesファイルに定義しただけではポートの予約なんてことは
できないんですね。

ITO様
>これは、システム予約ですね。
システム予約=「自由に割り当てしないように予約する」と思いたいのですが
実験結果を見た限りではそうでもないような気がしました。

で、ためしにFTPサービスを起動していないパソコンでFTPポート(21)を使って
TCPサーバポートを開いてみのたですが。

※netstatの表示
TCP home31:ftp home31:0 LISTENING

Listen状態になりました。

特定のポートを使用できるアプリを限定するとなると、ポートを開こうとし
ているアプリが何者なのかをOSが確認する手段が必要になるわけですよね。
そんな仕組みは聞いたことがないということは・・・。
どのアプリでも早いもの勝ちでポートを確保できるのはある意味、当然の
ことなのかな・・・と思いました。

結果、servicesファイルへの定義はポート番号とそのポートを使いたい「サービス
名称」の引当のみであり、ポートの実際取得は早いもの勝ちのように思います。

dogatana 様
レジストリにそのような定義があるのですね。
少しあとで試験してレポートします。
情報ありがとうございました。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました