使用setsockopt()接口,设置TCP的接收与发送超时,Invalid argument错误问题

使用TCP套接字时,当无网络连接时,还会继续send,继续recv阻塞,知道TCP自己协议机制判断断开连接时才会停止发送和接收,时间需要几分钟之久。
解决的办法是,自己设置接收超时时间,当超时后重新发送,或者从新初始化socket然后在重新创建socket重新connect
代码如下:  
         int iSendTimeout, iRecvTimeOut;
            iClientSock = socket(AF_INET, SOCK_STREAM, 0);
            if(iClientSock < 0)
            {
                        printf("[%s:%d]client init error\r\n", __FILE__, __LINE__);
                        return ERROR;
            }

            iRecvTimeOut = 3000;           
            iRet1 =  setsockopt(iClientSock, SOL_SOCKET, SO_RCVTIMEO, &iRecvTimeOut, sizeof(int));
            printf("%s\r\n", strerror(errno));
            iSendTimeout = 3000;           
            iRet2 =  setsockopt(iClientSock, SOL_SOCKET, SO_SNDTIMEO, (char *)&iSendTimeout, sizeof(int));
            printf("%s\r\n", strerror(errno));

但是编译会出错,perror显示参数错误( Invalid argument  ),看了下内核中的实现,参数确实错了,其中最后一个参数是sizeof( struct timeval) 类型的,而非其他类型
改正为:
struct timeval tv;    //声明一个 struct timeval 类型的变量
然后最后个参数写为:
iRet2=setsockopt(iClientSock, SOL_SOCKET, SO_SNDTIMEO, &iSendTimeout, sizeof(tv));

参数解析:
 int setsockopt(int s, int level, int optname,const void *optval, socklen_t optlen);
1) int s :sockfd,即socket文件描述符
2) int level :   SOL_SOCKET(通用套接字) ,IPPROTO_TCP,等
3)  int optname   : SO_SNDTIMEO(发送超时时间)| SO_RSVTIMEO(接收超时时间)等,设置选项,
4)  const void *optval :自定义的超时时间的地址
5)  struct timeval的大小,即 sizeof(struct timecal)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
setsockopt函数用于设置套接字选项。当使用setsockopt函数时,有时会遇到"Invalid argument"错误。这个错误通常是由于传递给setsockopt函数的参数不正确导致的。 引用中提到了使用setsockopt函数设置TCP接收发送超时时可能会遇到"Invalid argument"错误。这个错误通常是由于传递给setsockopt函数的参数类型不正确或者参数值不在允许的范围内导致的。 引用中提到了在使用setsockopt函数设置超时时,如果数据类型为int时报错"setsockopt invalid argument, errno 22"。这个错误通常是由于传递给setsockopt函数的参数类型不正确导致的。 为了解决这个问题,你可以确保传递给setsockopt函数的参数类型正确,并且参数值在允许的范围内。另外,你还可以参考相关文档或示例代码来确保正确使用setsockopt函数。 以下是一个示例代码,演示了如何使用setsockopt函数设置TCP接收发送超时: ```c #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <stdio.h> int main() { int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return -1; } struct timeval timeout; timeout.tv_sec = 5; // 设置超时时间为5秒 timeout.tv_usec = 0; if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0) { perror("setsockopt"); return -1; } if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) < 0) { perror("setsockopt"); return -1; } // 其他操作... return 0; } ``` 请注意,这只是一个示例代码,实际使用时需要根据具体情况进行修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值