TCP连接超时处理

这篇具有很好参考价值的文章主要介绍了TCP连接超时处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        在LINUX系统中,系统默认TCP建立连接超时时间为127秒。但是对于应用程序来说,这个超时时间太长了,不利于一些业务的处理。比如说我的应用想通过建立TCP连接来判断服务端程序是否在运行,或者网络是否通达,这时我不可能等127秒。那么应用程序如何实现TCP连接超时呢?

首先我们来看connect函数的帮助说明:

man connect
EINPROGRESS
              The socket is non-blocking and the connection cannot be completed immediately.  It is possible to select(2) or poll(2) for completion by selecting the socket  for  writing.   After  select(2)  indicates
              writability,  use  getsockopt(2)  to read the SO_ERROR option at level SOL_SOCKET to determine whether connect() completed successfully (SO_ERROR is zero) or unsuccessfully (SO_ERROR is one of the usual
              error codes listed here, explaining the reason for the failure).

解释如下:

        首先设置socket描述符为非阻塞模式,然后调用connect建立连接,此时连接操作不会立即完成,会返回错误码EINPROGRESS。然后使用select或者epoll来监测socket的写事件,如果超时时间内没有写事件到达,说明连接超时。如果有写事件时,需要获取socket错误码,错误为0时表示连接成功,错误码不为0时表示连接失败。

下面我们按照帮助说明编写一个简单的客户端demo程序来实现连接超时,供大家参考:文章来源地址https://www.toymoban.com/news/detail-536022.html

#include<sys/socket.h>
#include<sys/select.h>
#include<string.h>
#include<stdio.h>
#include<arpa/inet.h>
#include<errno.h>

int main(int argc,char *argv[])
{
	//设为非阻塞
	int sockfd = socket(AF_INET, SOCK_STREAM|SOCK_NONBLOCK, 0);
    printf("sockfd: %d\n", sockfd);

    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_port = htons(80); 
    sin.sin_addr.s_addr = inet_addr("192.168.1.2");
    socklen_t socklen = sizeof(struct sockaddr);
    int ret = connect(sockfd, (struct sockaddr*)&sin, socklen);
    printf("connect ret: %d\n", ret);
    if(ret != 0)
    {
		if(errno == EINPROGRESS)
		{
			fd_set writefds;
			FD_ZERO(&writefds);
			FD_SET(sockfd, &writefds);
			struct timeval stm;
			stm.tv_sec = 3;
			stm.tv_usec = 0;
			ret = select(sockfd+1, NULL, &writefds, NULL, &stm);
			printf("select ret: %d\n", ret);

			//没有写事件,表示连接超时
			//比如,对端不可达
			if(0 == ret)
			{
				printf("connect time out\n");
			}
			//有一个写事件
			else if (1 == ret)
			{
				if(FD_ISSET(sockfd, &writefds))
				{
					printf("fd is set\n");
					//连接成功时val为0
					//连接失败时val非0,比如对端没有绑定该端口,val返回111,连接拒绝
					int val;
					ret = getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &val, &socklen);

					printf("getsockopt ret: %d\n", ret);
					printf("err code: %d, [%s]\n", val, strerror(val));
				}
			}

		}
		else
		{
			printf("%s\n", strerror(errno));
		}
	}

	close(sockfd);
    return 0;
}

到了这里,关于TCP连接超时处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包