请问各位大侠,telnet能否设定超时连接

时间:2021-09-05 05:17:35
各位大侠,请问telnet能否象ftp那样,连接后超过一定的时间就会自动断开呢?该如何设置?

我是写在shell里,使用telnet $ip $port 来判断该通讯是否是好的,但现在的问题是如果该通讯不通,要等很久telnet $ip $port 才会自然退出,我希望设置telnet 的超时时间,比如设为3秒,不通的话就自动退出,也就认为该通讯不通,请问要如何设置?
谢谢!
telnet 192.168.1.10 8080 <<! 1>$HOME/log/err.log 2>&1
quit
!

20 个解决方案

#1


telnet没这个设置timeout的功能
自己写一个telnet的客户端 网上有源码 自己找一个改改  

#2


自己顶起,自己写一个有点麻烦,还有没有更好的简单一点的办法呢?

#3


可以使用expect

#4


写个expect脚本

#5


可以用C程序简单封装一下:
#include <stdio.h>

main()
{
        alarm(3);
        execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

#6


多谢各位,特别是jessiefn,你的这个方法我测试通过,多谢
不过我想进一步提高要求,就是如果这个通讯连接telnet过去,
如果会立即返回,那就立即返回,只有那种连接需要很长时间,才会
等3秒钟返回,也就是这个3秒是个最长的超时时间,但是你这种alarm(3);
是无论该连接是否会立即返回,都会等待3秒钟才会返回的,有没有办法
进一步优化下?谢谢

#7


自己顶起

#8


#include <stdio.h>
#include <unistd.h>

main()
{
        int fd[2];

        alarm(3);
        pipe(fd);

        write(fd[1], "\035", 1);      /* ^] */
        write(fd[1], "close\n", 6);
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);

        execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

如果不通,3秒后超时退出;
如果能通,立即退出。

另外,搭车问一下,我的专家分有好多,怎么下载时可用积分只有3分?

#9


多谢jessiefn,你的方法测试通过
你这个问题我也不清楚哦,我晚点结贴,看看有没有人知道你的问题

#10


用可用分可以兑换下载分,5:1
https://forum.csdn.net/PointForum/Forum/PointExchange.aspx

#11


还可以精简一下
#include <stdio.h>
#include <unistd.h>

main()
{
  int fd[2];

  alarm(3);
  pipe(fd);
  close(fd[1]);
  dup2(fd[0], STDIN_FILENO);

  execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

好了,结贴吧。

#12


谢谢jessiefn,不过我又遇到了一个新问题,我这个主机上有一个一直监听的进程comm,每当有进程连接该通讯进程的IP和端口时,该通讯进程comm就会fork一个子进程,本来正常telnet命令
/home1/nttqd_run/inspection> telnet 192.168.1.10 8080
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.
^]
telnet> q
Connection closed.
退出后,通讯进程comm程会退出,也就是ps -fu user|grep comm|wc -l 数量不会增加
但是你的这个程序,每执行一次,通讯进程comm数量就会增加一个,而且你的这个程序退出之后
增加通讯进程comm子进程不会退出,你的这个程序不断的执行的话,通讯进程comm数量就会不断的增加,
问下,这个新问题要如何解决呢?我希望你的这个检查连接的程序退出后,相对应的通讯进程comm也会
退出

#13


你的新fork的comm进程没有退出,它在干什么呢?
你这样还不如完全用C程序来实现呢,设定超时调用connect(),如果成功连接,就关闭描述符。

#14


嗯,我之前确实写了一个SOCKET程序来实现这个功能,代码如下
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>

//#define TIMEOUT 5
//#define SERV_PORT 7035
//#define SERV_PORT 7891

int main(int argc, char *argv[])
{
    char buff[100];
    int SERV_PORT;
    int TIMEOUT;

    //printf("argc=[%d]",argc);
    if(argc != 4)
    {
        printf("Usage: client xxx.xxx.xxx.xxx port timeout\nExample: client 192.168.0.1 port timeout\n");
        exit(1);
    }

    memset(buff,0,sizeof(buff));
    strcpy(buff,argv[2]);
    SERV_PORT=atoi(buff);
    
    memset(buff,0,sizeof(buff));
    strcpy(buff,argv[3]);
    TIMEOUT=atoi(buff);

    //printf("argc=[%d][%s][%d][%d]\n",argc,argv[1],SERV_PORT,TIMEOUT);

    int sockfd, flags, res,i;
    struct sockaddr_in servaddr;
    fd_set fdr, fdw;
    struct timeval timeout;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) {
        printf("Netwrok test...\n");
        goto PPP;
    }

    /* set socket fd noblock */
    if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) {
        printf("Netwrok test...\n");
        goto PPP;
    }
    
    if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
        printf("Network test...\n");
        goto PPP;
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    printf("Connected ip=[%s]port=[%d]..\n",argv[1],SERV_PORT);
    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
        if(errno != EINPROGRESS) { // EINPROGRESS 

            printf("Network test...\n");
                        goto PPP;
        }
    }
    else {
        printf("Connect函数出错\n");
        goto PPP;
    }
    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    FD_SET(sockfd, &fdr);
    FD_SET(sockfd, &fdw);

    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;

    res = select(sockfd + 1, &fdr, &fdw, NULL, &timeout);
    printf("res=[%d]",res);
    if(res < 0) {
        printf("Network test...\n");
        goto PPP;
    }
    if(res == 0) {
        printf("Connect server timeout\n");
        goto PPP;
    }
    if(res == 1) {
        //if(FD_ISSET(sockfd, &fdw))
        //{
            //SUCC关键字不能改变
            printf("Connected SUCC!\n");
                        goto PPP;
        //}

    }
    /* Not necessary */
    if(res == 2) {
        printf("Connect server timeout\n");
        goto PPP;
    }

    printf("Connect server timeout\n");
PPP:

    usleep(1000);
    printf("close sockfd...\n");
    close(sockfd);
    return 0;
}

但是这个程序在LINUX下运行没问题,可以正常检测通讯,但是在AIX系统下,虽然编译没问题,但是却不能正常运行,明明不通的连接,这个程序也是报的连通,即打印了Connected SUCC!,不知道怎么回事

#15


这又是一个新问题了,可以重开一帖了
jessiefn是高手啊,貌似在这个版很活跃啊

#16


学习了!

#17


汗颜,我只是偶尔来灌水哈~~
不能通过select()的返回值来判断是否成功吧。可以这样:
if( res < 0 ) 出错;
else if( res == 0 ) 超时;
int r = 0;
int iLen = sizeof(r);

if( getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&r, &iLen) < 0 ) 出错;
if( r ) 失败;

#18


简单一点的,可以利用SIGALRM信号。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <errno.h>

void foo(int sig) {}

int main(int argc, char *argv[])
{
    if( argc != 4 )
    {
        printf("Usage: %s xxx.xxx.xxx.xxx port timeout\nExample: %s 192.168.0.1 port timeout\n", argv[0], argv[0]);
        exit(1);
    }

    int sockfd;
    struct sockaddr_in servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        perror("socket");
        return 0;
    }

    signal(SIGALRM, foo);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(atoi(argv[2]));

    printf("Connecting to [%s:%d] ... ", argv[1], atoi(argv[2]));
    fflush(stdout);
    alarm(atoi(argv[3]));

    if( connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
    {
        printf("failed.\n");
        return 0;
    }

    printf("OK\n");
    return 0;
}

#19


jessiefn的方法测试通过,不过有点点改进的地方,我把修改的代码贴下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <errno.h>

int sockfd;

void foo(int sig) {
printf("timeout.\n");
usleep(1000);
  close(sockfd);
exit(1);
}

int main(int argc, char *argv[])
{
    if( argc != 4 )
    {
        printf("Usage: %s xxx.xxx.xxx.xxx port timeout\nExample: %s 192.168.0.1 port timeout\n", argv[0], argv[0]);
        exit(1);
    }

    
    struct sockaddr_in servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        perror("socket");
        return 0;
    }

    signal(SIGALRM, foo);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(atoi(argv[2]));

    printf("Connecting to [%s:%d] ... ", argv[1], atoi(argv[2]));
    fflush(stdout);
    alarm(atoi(argv[3]));

    if( connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
    {
     usleep(10000);
     close(sockfd);
        printf("failed.\n");
        return 0;
    }
    
    usleep(10000);
close(sockfd);
    printf("OK\n");
    return 0;
}


结贴

#20


其实进程退出前,会自动关闭所有打开着的描述符,无需显式关闭.

#1


telnet没这个设置timeout的功能
自己写一个telnet的客户端 网上有源码 自己找一个改改  

#2


自己顶起,自己写一个有点麻烦,还有没有更好的简单一点的办法呢?

#3


可以使用expect

#4


写个expect脚本

#5


可以用C程序简单封装一下:
#include <stdio.h>

main()
{
        alarm(3);
        execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

#6


多谢各位,特别是jessiefn,你的这个方法我测试通过,多谢
不过我想进一步提高要求,就是如果这个通讯连接telnet过去,
如果会立即返回,那就立即返回,只有那种连接需要很长时间,才会
等3秒钟返回,也就是这个3秒是个最长的超时时间,但是你这种alarm(3);
是无论该连接是否会立即返回,都会等待3秒钟才会返回的,有没有办法
进一步优化下?谢谢

#7


自己顶起

#8


#include <stdio.h>
#include <unistd.h>

main()
{
        int fd[2];

        alarm(3);
        pipe(fd);

        write(fd[1], "\035", 1);      /* ^] */
        write(fd[1], "close\n", 6);
        close(fd[1]);
        dup2(fd[0], STDIN_FILENO);

        execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

如果不通,3秒后超时退出;
如果能通,立即退出。

另外,搭车问一下,我的专家分有好多,怎么下载时可用积分只有3分?

#9


多谢jessiefn,你的方法测试通过
你这个问题我也不清楚哦,我晚点结贴,看看有没有人知道你的问题

#10


用可用分可以兑换下载分,5:1
https://forum.csdn.net/PointForum/Forum/PointExchange.aspx

#11


还可以精简一下
#include <stdio.h>
#include <unistd.h>

main()
{
  int fd[2];

  alarm(3);
  pipe(fd);
  close(fd[1]);
  dup2(fd[0], STDIN_FILENO);

  execlp("telnet", "telnet", "192.168.1.10", "8080", 0);
}

好了,结贴吧。

#12


谢谢jessiefn,不过我又遇到了一个新问题,我这个主机上有一个一直监听的进程comm,每当有进程连接该通讯进程的IP和端口时,该通讯进程comm就会fork一个子进程,本来正常telnet命令
/home1/nttqd_run/inspection> telnet 192.168.1.10 8080
Trying 192.168.1.10...
Connected to 192.168.1.10.
Escape character is '^]'.
^]
telnet> q
Connection closed.
退出后,通讯进程comm程会退出,也就是ps -fu user|grep comm|wc -l 数量不会增加
但是你的这个程序,每执行一次,通讯进程comm数量就会增加一个,而且你的这个程序退出之后
增加通讯进程comm子进程不会退出,你的这个程序不断的执行的话,通讯进程comm数量就会不断的增加,
问下,这个新问题要如何解决呢?我希望你的这个检查连接的程序退出后,相对应的通讯进程comm也会
退出

#13


你的新fork的comm进程没有退出,它在干什么呢?
你这样还不如完全用C程序来实现呢,设定超时调用connect(),如果成功连接,就关闭描述符。

#14


嗯,我之前确实写了一个SOCKET程序来实现这个功能,代码如下
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <errno.h>

//#define TIMEOUT 5
//#define SERV_PORT 7035
//#define SERV_PORT 7891

int main(int argc, char *argv[])
{
    char buff[100];
    int SERV_PORT;
    int TIMEOUT;

    //printf("argc=[%d]",argc);
    if(argc != 4)
    {
        printf("Usage: client xxx.xxx.xxx.xxx port timeout\nExample: client 192.168.0.1 port timeout\n");
        exit(1);
    }

    memset(buff,0,sizeof(buff));
    strcpy(buff,argv[2]);
    SERV_PORT=atoi(buff);
    
    memset(buff,0,sizeof(buff));
    strcpy(buff,argv[3]);
    TIMEOUT=atoi(buff);

    //printf("argc=[%d][%s][%d][%d]\n",argc,argv[1],SERV_PORT,TIMEOUT);

    int sockfd, flags, res,i;
    struct sockaddr_in servaddr;
    fd_set fdr, fdw;
    struct timeval timeout;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0) {
        printf("Netwrok test...\n");
        goto PPP;
    }

    /* set socket fd noblock */
    if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) {
        printf("Netwrok test...\n");
        goto PPP;
    }
    
    if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
        printf("Network test...\n");
        goto PPP;
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(SERV_PORT);

    printf("Connected ip=[%s]port=[%d]..\n",argv[1],SERV_PORT);
    if(connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) != 0) {
        if(errno != EINPROGRESS) { // EINPROGRESS 

            printf("Network test...\n");
                        goto PPP;
        }
    }
    else {
        printf("Connect函数出错\n");
        goto PPP;
    }
    FD_ZERO(&fdr);
    FD_ZERO(&fdw);
    FD_SET(sockfd, &fdr);
    FD_SET(sockfd, &fdw);

    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;

    res = select(sockfd + 1, &fdr, &fdw, NULL, &timeout);
    printf("res=[%d]",res);
    if(res < 0) {
        printf("Network test...\n");
        goto PPP;
    }
    if(res == 0) {
        printf("Connect server timeout\n");
        goto PPP;
    }
    if(res == 1) {
        //if(FD_ISSET(sockfd, &fdw))
        //{
            //SUCC关键字不能改变
            printf("Connected SUCC!\n");
                        goto PPP;
        //}

    }
    /* Not necessary */
    if(res == 2) {
        printf("Connect server timeout\n");
        goto PPP;
    }

    printf("Connect server timeout\n");
PPP:

    usleep(1000);
    printf("close sockfd...\n");
    close(sockfd);
    return 0;
}

但是这个程序在LINUX下运行没问题,可以正常检测通讯,但是在AIX系统下,虽然编译没问题,但是却不能正常运行,明明不通的连接,这个程序也是报的连通,即打印了Connected SUCC!,不知道怎么回事

#15


这又是一个新问题了,可以重开一帖了
jessiefn是高手啊,貌似在这个版很活跃啊

#16


学习了!

#17


汗颜,我只是偶尔来灌水哈~~
不能通过select()的返回值来判断是否成功吧。可以这样:
if( res < 0 ) 出错;
else if( res == 0 ) 超时;
int r = 0;
int iLen = sizeof(r);

if( getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char *)&r, &iLen) < 0 ) 出错;
if( r ) 失败;

#18


简单一点的,可以利用SIGALRM信号。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <errno.h>

void foo(int sig) {}

int main(int argc, char *argv[])
{
    if( argc != 4 )
    {
        printf("Usage: %s xxx.xxx.xxx.xxx port timeout\nExample: %s 192.168.0.1 port timeout\n", argv[0], argv[0]);
        exit(1);
    }

    int sockfd;
    struct sockaddr_in servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        perror("socket");
        return 0;
    }

    signal(SIGALRM, foo);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(atoi(argv[2]));

    printf("Connecting to [%s:%d] ... ", argv[1], atoi(argv[2]));
    fflush(stdout);
    alarm(atoi(argv[3]));

    if( connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
    {
        printf("failed.\n");
        return 0;
    }

    printf("OK\n");
    return 0;
}

#19


jessiefn的方法测试通过,不过有点点改进的地方,我把修改的代码贴下

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <netinet/in.h>
#include <errno.h>

int sockfd;

void foo(int sig) {
printf("timeout.\n");
usleep(1000);
  close(sockfd);
exit(1);
}

int main(int argc, char *argv[])
{
    if( argc != 4 )
    {
        printf("Usage: %s xxx.xxx.xxx.xxx port timeout\nExample: %s 192.168.0.1 port timeout\n", argv[0], argv[0]);
        exit(1);
    }

    
    struct sockaddr_in servaddr;

    if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    {
        perror("socket");
        return 0;
    }

    signal(SIGALRM, foo);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    inet_pton(AF_INET, argv[1], &servaddr.sin_addr);
    servaddr.sin_port = htons(atoi(argv[2]));

    printf("Connecting to [%s:%d] ... ", argv[1], atoi(argv[2]));
    fflush(stdout);
    alarm(atoi(argv[3]));

    if( connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0 )
    {
     usleep(10000);
     close(sockfd);
        printf("failed.\n");
        return 0;
    }
    
    usleep(10000);
close(sockfd);
    printf("OK\n");
    return 0;
}


结贴

#20


其实进程退出前,会自动关闭所有打开着的描述符,无需显式关闭.

#21