我有一个非常简单的问题。我想测试特定端口当前是否正在使用中。为此,我想将TCP套接字绑定到该端口,如果连接被拒绝,则表示该端口正在使用中,否则表示端口空闲。
请问有人可以告诉我如何在C语言中编写TCP套接字代码吗?我在Solaris平台上。
我知道这很基础。但是我感谢您的帮助。提前致谢。
如果出现错误,包括地址已经被使用的情况,调用bind函数将返回-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
。
即(修改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以下的任何端口)
正如Anonymous所建议的那样,您还可以查看netstat
。这将为您提供所有可以通过重复调用bind()
获得的相同信息,但速度更快且没有任何副作用(例如它不必实际绑定到端口,这会使它们对任何其他进程都不可用)。
只需调用netstat -a --numeric-ports -t
并分析输出,就可以获得您想要的所有内容。
关于moogs的建议,调用telnet每个端口只会告诉您该端口上是否有一个套接字在侦听 - 而不是它是否真的开放。
你只是想测试特定的端口是否正在被使用吗?(并不需要编写程序)。 如果是这样,你可以使用telnet:
telnet 主机名 端口号
如果连接失败,则该端口当前未被使用。如果连接成功并等待你的输入,则说明该端口正在被使用 :)