端口全连接扫描程序(Linux, socket):TCP的connect方式

来源:互联网 发布:知乎诈骗案 编辑:程序博客网 时间:2024/06/02 11:29

TCP建立连接需要使用三次握手协议。在Linux下的socket API,服务器使用socket, bind, listen, accept的过程打开并且监听端口,客户端使用socket,bind(可有可不有),connect的过程连接到服务器的某一个端口。当客户端要连接的服务器的端口开放,客户端利用connect可以通过三次握手协议正常建立连接。当客户端要连接的服务器的端口关闭,客户端connect到服务器的时候,服务器响应RST,客户端connect返回ECONNREFUSED错误。可以通过这个连接是否成功来判断端口是否打开。以下是端口扫描代码:


#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAXLINE 4098int main(int argc, char **argv){  int sockfd, n;  struct sockaddr_in servaddr;  //input the IP address and port(from argv[2] to argv[3])  if (argc != 4) {    printf("usage: fulfill the cmd\n");    return -1;  }  int i;  //atoi():char* to int  for (i = atoi(argv[2]); i < atoi(argv[3]); i++) {    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {      printf("socket error\n");      return -1;    }    //include in string.h    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(i);    //inet_pton include in <arpa/inet.h>    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {      printf("inet_pton error\n");    }    if (connect(sockfd, (struct sockaddr*) &servaddr, sizeof(servaddr)) < 0) {      //printf("unuseful port: %d\n", i);      close(sockfd);      continue;    }    else {      printf("useful port: %d\n", i);      close(sockfd);      continue;    }  }  exit(0);}

程序实例输出:


运行程序,输入要扫描的IP地址,起始端口号和最终端口号。然后就会列出打开的端口。这里我用127.0.0.1测试自己的电脑打开的可被连接的TCP端口。

程序解释:

程序是单进程的方式。

argc判断输入的命令是否正确。

atoi()将char *格式的字符串转换为int格式

整个过程都是正常的创建TCP socket和connect的过程,比较简单。

sockfd = socket()需要在for循环里面,因为TCP的套接字描述符不能重用,需要在每个TCP的connect创建连接之前重新创建一个新的套接字描述符。

每次connect之后都需要利用close()把套接字描述符关闭,从而释放系统资源,避免超过可创建描述符达到上限而无法创建新的套接字(关于上限的问题还需要进一步查资料)。关于套接字可以参考 http://hi.baidu.com/hwzaeolskllprze/item/efd6a7c617168750bcef69f7 加深理解。



0 0