2016-05-22 11 views
2

Cで単純なport scannerを作成しようとしていますが、最終段階になります。私はポート上のサーバに接続する簡単な関数を書いており、ポートが閉じているとタイムアウトするべきです。私は次のテストケースを持っています:ソケットをタイムアウトするためにselect()を使用する

問題は、私が渡したポートが開いているということです。たとえば、次のように

[[email protected]:~/SpinCloud/Chevron] [devel]$ ./testcase localhost 22 # sshd actually runs on this machine, so its correct 
connecting(): Operation now in progress 
port is open. 
[[email protected]:~/SpinCloud/Chevron] [devel]$ telnet localhost 22 
Trying 127.0.0.1... 
Connected to localhost. 
Escape character is '^]'. 
SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.6 
^] 

telnet> quit 
Connection closed. 
[[email protected]:~/SpinCloud/Chevron] [devel]$ ./testcase localhost 80 # but no webserver 
connecting(): Operation now in progress 
port is open. 
[[email protected]:~/SpinCloud/Chevron] [devel]$ telnet localhost 80 
Trying 127.0.0.1... 
telnet: Unable to connect to remote host: Connection refused 
[[email protected]:~/SpinCloud/Chevron] [devel]$ 

答えて

4

「読める」または「書き込み可能」としてselectレポートの何かが唯一read/writeへの試みがブロックされないことを意味しているという事実。 の結果がread/writeになることは何も意味しません。

注:また、connectEINPROGRESS(およびその場合の書き込み可能性についてのポーリング)を返す場合を区別して、他の失敗から区別する必要があります。 (多分あなたの代わりにTCP_KEEPCNTまたはTCP_USER_TIMEOUTを使うだろうか?しかし、それは動作しないでしょうけれども、あなたがになっているようgetaddrinfoを使用し、潜在的に一度アドレスのすべてを試してみましたが、それぞれの間の遅延を持つ場合)

また、poll(これはPOSIXです)のいずれかが、システム固有のものでなければ、epollkqueueのような、より新しい選択肢を真剣に検討するべきです。

2

ノンブロッキングリクエストを開いています。あなたはconnect()を呼び出すとmanpage for connect()で説明したように、それは、「操作が進行中である」EINPROGRESSを返し、または:

  The socket is nonblocking and the connection cannot be 
      completed immediately. It is possible to select(2) or poll(2) 
      for completion by selecting the socket for writing. After 
      select(2) indicates writability, use getsockopt(2) to read the 
      SO_ERROR option at level SOL_SOCKET to determine whether 
      connect() completed successfully (SO_ERROR is zero) or 
      unsuccessfully (SO_ERROR is one of the usual error codes 
      listed here, explaining the reason for the failure). 

あなたは接続のerrno値を確認する必要があります()。また、返されたnonnegative selectは、必ずしもポートがあなたがテストしているサーバー上で開いていることを意味しません。

あなたが投稿したコードは、一般的にエラーをうまく処理するものではありません。最初のif(argc != 3) {から、返信するのではなくメッセージを印刷するだけです。 3つの入力をせずにコードを実行すると、エラーが表示されますが、実行を続行します(おそらくsegフォールトで終了します)。

同期と非同期の入出力を調査し、ポートが開いていると仮定する前にポートに実際に接続するより多くの時間を費やすことをお勧めします。

+0

が記載されている。お勧めの読書先はありますか? – DTSCode

+0

@DTSCodeすべてのマニュアルページを読むのは素晴らしいスタートです。それらの* lot *があります。 – o11c

関連する問題