日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何解决Connect超时导致的阻塞问题

發布時間:2025/4/5 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何解决Connect超时导致的阻塞问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

版權聲明:本文為博主原創文章,遵循 CC 4.0 by-sa 版權協議,轉載請附上原文出處鏈接和本聲明。
本文鏈接:https://blog.csdn.net/clirus/article/details/50577352
????????這幾天發現一個現象,客戶端正常連接服務器connect顯然不會出現問題。

????????在異常情況下,如果是服務器出現異常,connect能夠立即返回失敗;但是當客戶端出現異常的情況下,分為兩種情況:

????????一種是不插網線,客戶端沒有獲得ip地址,在這種情況下,connect也可以立即返回錯誤;

????????二是但是當客戶端插上網線,但是連接網絡失敗,也就是說能夠獲取到ip地址,但是和服務器是ping不通的。這種情況下connect就可能會發生阻塞,因為按照《UNIX 網絡編程》中講解,connect的在進行三次握手,如果失敗情況,需要等待75s的超市時間的。

????????我們主要討論第二種情況如何解決,可以讓connect快速返回結果,不至于阻塞等待超長的時間。

????????如下是我的代碼

/******************************
* Time out for connect()
******************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
?
?
#define TIME_OUT_TIME 20 //connect超時時間20秒
?
bool setBlockOpt(int m_fd,bool blocked)
{
?? ??? ??? ?
#ifndef WIN32
?? ?int ?flags;
?? ?flags = fcntl(m_fd, F_GETFL, 0);
?? ?if(flags < 0)
?? ?{
?? ??? ?return false;
?? ?}
?? ?if(blocked)
?? ?{?? ?
?? ??? ?printf("Set BLOCK !!!\n");
?? ??? ?flags &= ~O_NONBLOCK;
?? ?}
?? ?else
?? ?{
?? ??? ?printf("Set NONBLOCK !!!\n");
?? ??? ?flags |= O_NONBLOCK;
?? ?}
?? ?if(fcntl(m_fd, F_SETFL, flags) < 0)
?? ?{
?? ??? ?return false;
?? ?}
?? ?
#else
?? ?u_long ulValue;
?? ?if(blocked)
?? ?{
?? ??? ?ulValue = 1;
?? ?}
?? ?else
?? ?{
?? ??? ?ulValue = 0;
?? ?}?? ?
?? ?int n = ioctlsocket(m_fd, FIONBIO, &ulValue);
?? ?if (n != 0)
?? ?{
?? ??? ?return false;
?? ?}
#endif
?? ?return true;
}
?
int connectWithTimeout(int m_fd,int timeout)
{
?? ?int selectFlag = -1;
?? ?int error=-1, len;
?? ?len = sizeof(int);
?? ?bool ret = false;
?? ?int connectFlag = -1;
?? ?
?? ?const char* m_ip = "115.239.210.27";
?? ?int m_port = 80;
?? ?
?? ?if("" == m_ip || 0 > m_port)
?? ?{
?? ??? ?return -1;
?? ?}
?? ?
?? ?if(m_fd < 0 && "" != m_ip && m_port >=0)
?? ?{
?? ??? ?m_fd = ?socket(AF_INET, SOCK_STREAM, 0);
?? ??? ?if(m_fd < 0)
?? ??? ?{
?? ??? ??? ?return -1;
?? ??? ?}
?? ?}
?? ?
?? ?if(m_fd < 0)
?? ?{
?? ??? ?return -1;
?? ?}
?
?? ?struct sockaddr_in servAddr;
?? ?memset(&servAddr, 0, sizeof(servAddr));
?? ?servAddr.sin_family = AF_INET;
?? ?servAddr.sin_port = htons((unsigned short)m_port);
?? ?servAddr.sin_addr.s_addr = inet_addr(m_ip);
?
?? ?setBlockOpt(m_fd,false);?? ?//設置為非阻塞模式
?? ?if( (connectFlag= connect(m_fd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0))
?? ?{
?? ??? ?if(errno != EINPROGRESS)
?? ??? ?{
?? ??? ??? ?goto done;
?? ??? ?}
?? ?}
?? ?else
?? ?{
?? ??? ?ret = true;
?? ??? ?goto done;
?? ?}
?? ?timeval tm;
?? ?tm.tv_sec = timeout/1000;
?? ?tm.tv_usec = timeout%1000;
?? ?fd_set rest, west;
?? ?FD_ZERO(&rest);
?? ?FD_ZERO(&west);
?? ?FD_SET(m_fd, &rest);
?? ?FD_SET(m_fd, &west);
?
?? ?if( (selectFlag = select(m_fd+1, &rest, &west, NULL, &tm)) > 0)
?? ?{
?? ??? ?//如果套接口及可寫也可讀,需要進一步判斷
?? ??? ?if(FD_ISSET(m_fd, &rest) && FD_ISSET(m_fd, &west))?
?? ??? ?{
?? ??? ??? ?if(getsockopt(m_fd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len) < 0)
?? ??? ??? ?{
?? ??? ??? ??? ?printf("getsockopt error!!!\n");
?? ??? ??? ?}
?? ??? ??? ?else
?? ??? ??? ?{
?? ??? ??? ??? ?if(error == 0)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?ret = true;
?? ??? ??? ??? ?}
?? ??? ??? ??? ?else?
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?printf("connect getsockopt error!!! %d\n",error);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ??? ?//如果套接口可寫不可讀,則鏈接完成
?? ??? ?else if(FD_ISSET(m_fd, &west) && !FD_ISSET(m_fd, &rest))?
?? ??? ?{?
?? ??? ??? ?ret = true;
?? ??? ?}
?? ?}
?? ?else if(selectFlag == 0)
?? ?{
?? ??? ?printf("connect select timeout!!!\n");
?? ?}
?? ?else?
?? ?{
?? ??? ?printf("connect select error!!!\n");
?? ?}
?? ?
done:
?? ?setBlockOpt(m_fd,true);// 設置為阻塞模式
?? ?if(!ret)
?? ?{
?? ??? ?return -1;
?? ?}
?? ?return 0;
}
?
?
int main(int argc,char* argv[])
{
?? ?if(argc <= 1)
?? ?{
?? ??? ?printf("input error!!!\n");
?? ??? ?exit(1);
?? ?}
?? ?int sockfd = socket(AF_INET, SOCK_STREAM, 0);
?? ?if(sockfd < 0)?
?? ?{
?? ??? ?exit(1);
?? ?}
?? ?if(connectWithTimeout(sockfd,atoi(argv[1])) == 0)
?? ?{
?? ??? ?printf("connect sucess!!!\n");
?? ?}
?? ?else
?? ?{
?? ??? ?printf("connect filed!!!\n");
?? ?}
?? ?close(sockfd);
?? ?
?? ?
?? ?return 0;
}


??????

???????原理很簡單,就是先把套接字設置為非阻塞,因為在非阻塞情況下,connect的結果是立即返回的,然后我們再使用select或者poll等機制來檢測套接字一定的時間,如果在超時時間內不可寫,則認為connect失敗,然后需要把套接字重新設置為阻塞,當然如果你不需要在阻塞模式下工作,可以不用設置。

??????如上,我們就可以對connect的超時進行可控。
---------------------?
版權聲明:本文為CSDN博主「clirus」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/clirus/article/details/50577352

總結

以上是生活随笔為你收集整理的如何解决Connect超时导致的阻塞问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 狼人精品一区二区三区在线 | 午夜a视频 | 欧美在线天堂 | 在线免费观看日韩av | 91精品久久久久久久久久入口 | 黄色一级大片在线免费看国产一 | 日日夜夜狠 | 强行糟蹋人妻hd中文字幕 | 国产欧美一区二区三区另类精品 | 在线成人av网站 | 日本一区二区视频在线观看 | 波多野结衣有码 | 亚洲色图另类 | 成人免费在线观看网站 | 香蕉视频黄污 | 91免费看视频 | 久久资源365| 黑人乱码一区二区三区av | 欧美福利一区二区三区 | 成人性生活免费视频 | 精品无码一区二区三区蜜臀 | 成人一级视频在线观看 | 日韩国产精品一区二区三区 | 可以免费观看的av网站 | 日韩视频在线一区二区 | 中文字幕av高清 | 久久9热| 中文字幕av一区二区三区人妻少妇 | 免费一区二区视频 | 日韩在线免费观看视频 | 91射| 国产精品久久777777换脸 | 日本激情视频一区二区三区 | www.污网站 | 新x8x8拨牐拨牐永久免费影库 | xxx性欧美| 欧美激情小视频 | 天天干,天天操 | 亚洲制服av | 国产毛片91 | 中文字幕无码精品亚洲35 | 少妇在线观看 | 好色999 | 亚洲欧美日韩成人 | 在线a网站| 91视频免费观看网站 | 九九热最新网址 | 天堂网av手机版 | 中文字幕一区二区三区四区不卡 | 日批黄色片 | 大屁股白浆一区二区 | 国产精品日韩一区二区 | 国产在线视频卡一卡二 | 日本一区二区三区在线看 | 国产免费无码XXXXX视频 | 久久久久久久美女 | 白嫩情侣偷拍呻吟刺激 | 亚洲欧美激情另类校园 | 狠狠干b| 成年人av网站 | 天天色影| 亚洲欧美一区二区在线观看 | 欧美污视频在线观看 | 日本一二三视频 | 极品美女av| 神马午夜场 | 欧美重口另类 | 99久久精品免费看国产 | 成人免费xxxxx在线观看 | 永久免费无码av网站在线观看 | 饥渴的少妇和男按摩师 | 撸啊撸在线视频 | 国产精品国产三级国产aⅴ9色 | 男女污污视频在线观看 | 色婷婷九月 | 成人av在线网站 | 中文字幕日韩国产 | 精品无码国产污污污免费网站 | 国产激情一区二区三区 | 精品日本一区二区 | 蜜桃导航-精品导航 | 伊人开心网 | 日韩一区二区三 | 午夜在线你懂的 | 一区二区三区波多野结衣 | 久久99精品久久久久久园产越南 | 亚洲欧美日韩国产成人精品影院 | 国产伦理在线观看 | 成人午夜精品一区二区三区 | 国产一区二区三区久久 | 亚洲色图偷拍视频 | 91插插影库 | 精彩视频一区二区 | 成在线人免费视频 | 宅男视频污 | 国产爽视频| 红桃视频一区 | a免费在线 | 色视频线观看在线播放 |