Cを使用して事前定義されたポートに接続するTCPソケットを作成する方法
質問
非常に簡単な質問があります。特定のポートが現在使用されているかどうかをテストします。このため、TCPソケットをポートにバインドします。接続が拒否された場合はポートが使用中であり、そうでない場合はポートが空いていることを意味します。
CでTCPソケットコードを記述する方法を教えてください。 solarisプラットフォームを使用しています。
非常に基本的なことを知っています。しかし、私はあなたの助けに感謝します。事前に感謝します。
解決
バインド関数の呼び出しは、エラーがある場合に-1を返します。これには、アドレスが既に使用されている場合も含まれます。
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define PORT 12345
int main()
{
struct sockaddr_in addr;
int fd;
fd = socket(AF_INET, SOCK_STREAM, 0);
if(fd == -1)
{
printf("Error opening socket\n");
return -1;
}
addr.sin_port = htons(PORT);
addr.sin_addr.s_addr = 0;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_family = AF_INET;
if(bind(fd, (struct sockaddr *)&addr,sizeof(struct sockaddr_in) ) == -1)
{
printf("Error binding socket\n");
return -1;
}
printf("Successfully bound to port %u\n", PORT);
}
他のヒント
テストしようとしている内容にわずかに依存します。
joelcが提案した方法で bind()
を使用すると、マシンの任意のインターフェイスでポートが開いているかどうかがわかります。徹底的ですが、 bind()
からの戻り値をチェックするだけでなく、 errno == EADDRINUSE
もチェックする必要があります。
ie。 (joelcのコードの変更)
if(bind(socket, (struct sockaddr *)&sin,sizeof(struct sockaddr_in) ) == -1)
{
if( errno == EADDRINUSE )
{
// handle port already open case
}
else
{
// handle other errors
}
}
行で使用されるアドレスを変更することにより:例:
sin.sin_addr.s_addr = inet_addr("192.168.1.1");
...特定のインターフェイスでポートが使用可能かどうかをテストできます。
これはポート状態の完全なテストではないことに注意してください。別のプロセスがポートを開いていて、ポートを正常に閉じる前に終了した場合(つまり、ソケットで close()
を呼び出す前)、通常は同じ EADDRINUSE
を取得します。エラー。
(SO_REUSEADDRオプションがソケットに設定されているかどうかによります)
(補足:テストアプリケーションが十分な権限で実行されていない限り、1024未満のポートにbind()することはできません)
匿名が示唆したように、 netstat
も見ることができます。これにより、 bind()
を繰り返し呼び出して、副作用なしで取得できるのと同じ情報がすべて得られます(実際にポートにバインドする必要がなく、他のプロセスでは使用できなくなります)。
netstat -a --numeric-ports -t
を呼び出して出力を分析するだけで、目的のすべてが得られます。
ムーグの提案に関するコメント-各ポートでtelnetを呼び出すと、ソケットがそのポートでリッスンしているかどうかだけがわかり、実際に開いているかどうかはわかりません。
特定のポートが現在使用されているかどうかだけをテストしますか? (そして、実際にプログラムを作成する必要はありません)。 その場合、telnetを使用できます。
telnetホストポート
接続が失敗した場合、使用されていません。接続し、あなたからの入力を待っている場合、それは使用中です:)
netstatのソースコードを見ることもできます。 Solarisにもnetstatがあると思います。