麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 服務(wù)器 > Linux服務(wù)器 > 正文

Linux下connect超時(shí)處理(總結(jié))

2024-09-05 23:03:51
字體:
供稿:網(wǎng)友

1、前言

最近在寫一個(gè)測試工具,要求快速的高效率的掃描出各個(gè)服務(wù)器開放了哪些端口。當(dāng)時(shí)想了一下,ping只能檢測ip,判斷服務(wù)器的網(wǎng)絡(luò)是連通的,而不能判斷是否開放了端口。我們知道端口屬于網(wǎng)絡(luò)的傳輸層,因此需要用ip和端口來探測,這個(gè)時(shí)候就可以用connect來探測一下,針對TCP協(xié)議,connect函數(shù)要進(jìn)行TCP三次握手,如果connect成功,則說明服務(wù)器開放了某個(gè)端口,如果connect失敗,則說明服務(wù)器沒有開放某個(gè)端口。而connect失敗是通過超時(shí)來控制的,在規(guī)定的時(shí)間內(nèi),connect會發(fā)起多次連接,一直執(zhí)行到超時(shí),才返回錯(cuò)誤。默認(rèn)情況下,connect是阻塞的,而且默認(rèn)的超時(shí)時(shí)間為75s,正常情況下,檢測網(wǎng)絡(luò)的連通性都是毫秒級,如果要判斷10萬臺服務(wù)器的,用阻塞的默認(rèn)的connect去做,效率非常低下。因此采用非阻塞的connect,而且需要自定義超時(shí)間(我自定義超時(shí)時(shí)間為5s)。

2、非阻塞connect

對于阻塞式套接字,調(diào)用connect函數(shù)將激發(fā)TCP的三次握手過程,而且僅在連接建立成功或者出錯(cuò)時(shí)才返回;對于非阻塞式套接字,如果調(diào)用connect函數(shù)會之間返回-1(表示出錯(cuò)),且錯(cuò)誤為EINPROGRESS,表示連接建立,建立啟動但是尚未完成;如果返回0,則表示連接已經(jīng)建立,這通常是在服務(wù)器和客戶在同一臺主機(jī)上時(shí)發(fā)生。

select是一種IO多路復(fù)用機(jī)制,它允許進(jìn)程指示內(nèi)核等待多個(gè)事件的任何一個(gè)發(fā)生,并且在有一個(gè)或者多個(gè)事件發(fā)生或者經(jīng)歷一段指定的時(shí)間后才喚醒它。connect本身并不具有設(shè)置超時(shí)功能,如果想對套接字的IO操作設(shè)置超時(shí),可使用select函數(shù)。

對于select和非阻塞connect,注意兩點(diǎn):[1] 當(dāng)連接成功建立時(shí),描述符變成可寫; [2] 當(dāng)連接建立遇到錯(cuò)誤時(shí),描述符變?yōu)榧纯勺x,也可寫,遇到這種情況,可調(diào)用getsockopt函數(shù)。

3、實(shí)現(xiàn)步驟

(1) 創(chuàng)建socket,并利用fcntl將其設(shè)置為非阻塞

(2) 調(diào)用connect函數(shù),如果返回0,則連接建立;如果返回-1,檢查errno ,如果值為 EINPROGRESS,則連接正在建立。

(3) 為了控制連接建立時(shí)間,將該socket描述符加入到select的可讀可寫集合中,采用select函數(shù)設(shè)定超時(shí)。

(4) 如果規(guī)定時(shí)間內(nèi)成功建立,則描述符變?yōu)榭蓪懀环駝t,采用getsockopt函數(shù)捕獲錯(cuò)誤信息

(5) 恢復(fù)套接字的文件狀態(tài)并返回。

測試代碼如下所示:

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/types.h>     /* See NOTES */#include <sys/socket.h>#include <netinet/in.h>#include <fcntl.h>#include <errno.h>int main(int argc, char **argv){  if (argc < 3) {    printf("please input ip and port, for example ./main 120.12.34.56 80./n");    return -1;  }    char *ipaddr = argv[1];  unsigned int port = atoi(argv[2]);  int fd = 0;  struct sockaddr_in addr;  fd_set fdr, fdw;  struct timeval timeout;  int err = 0;  int errlen = sizeof(err);  fd = socket(AF_INET,SOCK_STREAM,0);  if (fd < 0) {    fprintf(stderr, "create socket failed,error:%s./n", strerror(errno));    return -1;  }  bzero(&addr, sizeof(addr));  addr.sin_family = AF_INET;  addr.sin_port = htons(port);  inet_pton(AF_INET, ipaddr, &addr.sin_addr);  /*設(shè)置套接字為非阻塞*/  int flags = fcntl(fd, F_GETFL, 0);  if (flags < 0) {    fprintf(stderr, "Get flags error:%s/n", strerror(errno));    close(fd);    return -1;  }  flags |= O_NONBLOCK;  if (fcntl(fd, F_SETFL, flags) < 0) {    fprintf(stderr, "Set flags error:%s/n", strerror(errno));    close(fd);    return -1;  }  /*阻塞情況下linux系統(tǒng)默認(rèn)超時(shí)時(shí)間為75s*/  int rc = connect(fd, (struct sockaddr*)&addr, sizeof(addr));  if (rc != 0) {    if (errno == EINPROGRESS) {      printf("Doing connection./n");      /*正在處理連接*/      FD_ZERO(&fdr);      FD_ZERO(&fdw);      FD_SET(fd, &fdr);      FD_SET(fd, &fdw);      timeout.tv_sec = 10;      timeout.tv_usec = 0;      rc = select(fd + 1, &fdr, &fdw, NULL, &timeout);      printf("rc is: %d/n", rc);      /*select調(diào)用失敗*/      if (rc < 0) {        fprintf(stderr, "connect error:%s/n", strerror(errno));        close(fd);        return -1;      }            /*連接超時(shí)*/      if (rc == 0) {        fprintf(stderr, "Connect timeout./n");        close(fd);        return -1;      }      /*[1] 當(dāng)連接成功建立時(shí),描述符變成可寫,rc=1*/      if (rc == 1 && FD_ISSET(fd, &fdw)) {        printf("Connect success/n");        close(fd);        return 0;      }      /*[2] 當(dāng)連接建立遇到錯(cuò)誤時(shí),描述符變?yōu)榧纯勺x,也可寫,rc=2 遇到這種情況,可調(diào)用getsockopt函數(shù)*/      if (rc == 2) {        if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen) == -1) {          fprintf(stderr, "getsockopt(SO_ERROR): %s", strerror(errno));          close(fd);          return -1;        }        if (err) {          errno = err;          fprintf(stderr, "connect error:%s/n", strerror(errno));          close(fd);          return -1;        }      }    }     fprintf(stderr, "connect failed, error:%s./n", strerror(errno));    return -1;  }   return 0;}

linux,c,connect,超時(shí)

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持VEVB武林網(wǎng)。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本免费不卡一区二区 | 日本a∨精品中文字幕在线 欧美1—12sexvideos | 91久久国产露脸精品免费 | 欧美一级二级毛片视频 | 久草在线视频免费播放 | 精品麻豆cm视频在线看 | 秋霞a级毛片在线看 | 海外中文字幕在线观看 | 沉沦的校花奴性郑依婷c到失禁 | 色播视频在线播放 | 免费视频a | 美国一级黄色毛片 | 91久久精品国产亚洲 | 国产精品亚洲精品日韩已方 | 久久久久久久免费精品 | 99国产精品国产免费观看 | 一级免费观看 | 久久国产亚洲视频 | 91精品观看91久久久久久国产 | 4p一女两男做爰在线观看 | 九九热免费精品视频 | 国产一区二区三区影视 | 久草在线免费资源站 | 亚洲字幕av| 黄色av网站免费 | 欧美另类在线视频 | 日韩黄色片免费看 | 久久久一二三 | 国产精品成人免费一区久久羞羞 | 日韩毛片毛片久久精品 | av手机在线免费播放 | 精品一区二区三区不卡 | 中文字幕在线观看1 | 国产精品久久久久一区二区 | 久久精品色 | 国产一区免费 | 日韩av电影免费在线观看 | 亚洲精品一区中文字幕 | 色中色综合 | 97zyz成人免费视频 | www.99热视频|