大家都知道,linux中有telnet命令,用于探测tcp连接,功能强大。
最近,我写了一个这个命令,试了一下,靠谱:
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <netdb.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <errno.h>
- #include <malloc.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/ioctl.h>
- #include <stdarg.h>
- #include <fcntl.h>
- #include <time.h>
-
-
- int telnetCheckTcp(const char *ip, int port, int tSecond)
- {
- int sockClient = socket(AF_INET, SOCK_STREAM, 0);
- int iFinal = 0;
-
- struct sockaddr_in addrSrv;
- addrSrv.sin_addr.s_addr = inet_addr(ip);
- addrSrv.sin_family = AF_INET;
- addrSrv.sin_port = htons(port);
-
- fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0)|O_NONBLOCK);
-
- int iRet = connect(sockClient, ( const struct sockaddr *)&addrSrv, sizeof(struct sockaddr_in)); // 返回-1不一定是异常
- if (iRet != 0)
- {
- if(errno != EINPROGRESS)
- {
- iFinal = -1;
- }
- else
- {
- struct timeval tm = {tSecond, 0};
- fd_set wset, rset;
- FD_ZERO(&wset);
- FD_ZERO(&rset);
- FD_SET(sockClient, &wset);
- FD_SET(sockClient, &rset);
- int time1 = time(NULL);
- int n = select(sockClient + 1, &rset, &wset, NULL, &tm);
- int time2 = time(NULL);
-
- if(n < 0)
- {
- iFinal = -2;
- }
- else if(n == 0)
- {
- iFinal = -3;
- }
- else if (n == 1)
- {
- if(FD_ISSET(sockClient, &wset))
- {
- iFinal = 0;
- fcntl(sockClient, F_SETFL, fcntl(sockClient, F_GETFL, 0) & ~O_NONBLOCK);
- }
- else
- {
- iFinal = -4;
- }
- }
- else
- {
- iFinal = -5;
- }
- }
- }
-
- close(sockClient);
- return iFinal;
- }
-
-
- int main(int argc, char *argv[])
- {
- if(argc != 4)
- {
- printf("error\n");
- return -1;
- }
-
- int iFinal = telnetCheckTcp(argv[1], atoi(argv[2]), atoi(argv[3]));
- printf("iFinal is %d\n", iFinal);
-
- return 0;
- }
经调试,OK.