c语⾔connect函数,LinuxC语⾔connect的超时设置(含源码和
例程)
0x01 关键步骤和相关函数
⽹络编程中默认情况下进⼊connect函数,会⼀直等待连接结束。超时等待设置关键在于
1、将socket置为⾮阻塞后
2、设定超时等待时间
3、时间结束后读取socket状态,进⾏判断
1、设置socket为⾮阻塞
记录下两种设置socket为⾮阻塞⽅式,分别是fcntl() 和 ioctl() 两个函数fcntl()#include
#include
/*********************************************************************
* Function : fcntl
* Description : 根据⽂件描述符操作⽂件特性
* Parameter :
* @fd ⽂件描述符
* @cmd 操作命令:
* F_DUPFD : 复制⽂件描述词。
* FD_CLOEXEC : 设置close-on-exec标志
* F_GETFD : 读取⽂件描述词标志
* F_SETFD : 设置⽂件描述词标志
* F_GETFL : 读取⽂件状态标志
* F_SETFL : 设置⽂件状态标志
* ...
* @arg 供命令使⽤的参数
*
* Return : int
*
* Usage :
* int fcntl(int fd, int cmd);
* int fcntl(int fd, int cmd, long arg);
* int fcntl(int fd, int cmd, struct flock *lock);
*
* 参考 man 或:
*
*********************************************************************/
int fcntl(int fd, int cmd, ... /* arg */ );ioctl()#include
/*********************************************************
* Function : ioctl
* Description : 设备驱动程序中对设备的I/O通道进⾏管理的函数* Parameter :
* @fd ⽂件描述符
* @request 操作命令:
* FIONBIN : 设置/ 清除⾮阻塞I/O 标志
* FIOASYNC : 设置/ 清除信号驱动异步I/O 标志
* FIONREAD : 获取接收缓存区中的字节数
* FIOSETOWN : 设置⽂件的进程ID 或进程组ID
* FIOGETOWN : 获取⽂件的进程ID 或进程组ID
* ...
* @arg 供命令使⽤的参数
*
* Return : int
*
* 参考 man 或:
* 上⽂详细介绍了该函数的⽤途
* 以及request对应参数所需要提供的arg类型
*********************************************************/
int ioctl(int fd, unsigned long request, .../* arg */);
2、超时等待select() 多路复⽤#include
#include
#include
#include
/*********************************************************
* Function : select
* Description : 同步I/O多路复⽤
* Parameter :
* @nfds ⽂件描述符+1
* @readfds 可读⽂件描述符词组
* @writefds 可写⽂件描述符词组
* @exceptfds 例外⽂件描述符词组
* @timeout 等待时间
*
* Return : int
*
* 参考 man 或:
*
*********************************************************/
int select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout);
/
**
* 相关函数
*/
void FD_ZERO(fd_set *set); // 清除描述符词组set的全部位
void FD_CLR(int fd, fd_set *set); // 清除描述符词组set中相关fd的位
void FD_SET(int fd, fd_set *set); // 设置描述符词组set中相关fd的位
int FD_ISSET(int fd, fd_set *set); // 测试描述符词组set中相关fd的位是否为真3、获取socket状态#include
#include
/*********************************************************
* Function : getsockopt
* Description : 返回指定socket的状态
* Parameter :
* @sockfd socket的⽂件描述符
* @level 操作的⽹络层, ⼀般设置为SOL_SOCKET
* @optname 操作的选项:
* SO_DEBUG 打开或关闭排错模式
* SO_REUSEADDR 允许在bind ()过程中本地地址可重复使⽤
* SO_TYPE 返回socket 形态.
* SO_ERROR 返回socket 已发⽣的错误原因
* SO_DONTROUTE 送出的数据包不要利⽤路由设备来传输.
* SO_BROADCAST 使⽤⼴播⽅式传送
* SO_SNDBUF 设置送出的暂存区⼤⼩
* SO_RCVBUF 设置接收的暂存区⼤⼩
* SO_KEEPALIVE 定期确定连线是否已终⽌.
* SO_OOBINLINE 当接收到OOB 数据时会马上送⾄标准输⼊设备
* SO_LINGER 确保数据安全且可靠的传送出去.
* @optval 保存结果的内存地址
timeout on t2 timer* @optlen optval空间的⼤⼩
*
* Return : 成功则返回0, 若有错误则返回-1, 错误原因存于errno
* errno:
* EBADF 参数s 并⾮合法的socket 处理代码
* ENOTSOCK 参数s为⼀⽂件描述词, ⾮socket
* ENOPROTOOPT 参数optname指定的选项不正确
* EFAULT 参数optval指针指向⽆法存取的内存空间
*
* 参考 man 或:
*
*********************************************************/
int getsockopt(int sockfd, int level, int optname,
void *optval, socklen_t *optlen);
0x02 例程代码
本例程为⼀份检测本地与⽬标端⼝连接是否活跃的程序,只封装了建⽴⼀个普通TCP带有超时参数的客户端connect函数。头⽂件 -Network.h/*************************************************************************
> File Name: Network.h
> Author: WangMinghang
> Mail: hackxiaowang@qq
> Created Time: 2019年04⽉29⽇ 星期⼀ 10时32分21秒
************************************************************************/
#ifndef __USER_NETWORK_H__
#define __USER_NETWORK_H__
/************************************************************
* Function : create_connect
* Description : 创建⼀个TCP连接的客户端socket, 并设置超时时间
* Parameter :
* @host 主机域名或IP地址
* @port ⽬标端⼝
* @s 连接超时时间, 单位: 秒
* Return :
* 连接成功 - 返回socket描述符
* 连接失败 - 返回值⼩于0
* -1 : 创建socket失败
* -2 : 连接超时
*
************************************************************/
int create_connect(const char *host, int port, int s);
#endifmain 主程序 - Network_test.c/************************************************************************* > File Name: Network_test.c
> Author: WangMinghang
> Mail: hackxiaowang@qq
> Created Time: 2019年04⽉29⽇ 星期⼀ 10时32分21秒
************************************************************************/
#include
#include
#include
#include "Network.h"
#define TIMEOUT 3
#define SERVER_PORT 80
#define SERVER_HOST "www.wangsansan"
void delay_ms(int timeout);
int main(int argc, char **argv)
{
int sock_fd = -1;
while(1)
{
sock_fd = create_connect(SERVER_HOST, SERVER_PORT, TIMEOUT);
if(sock_fd <= 0){
printf("Connect failed - %d \n", sock_fd);
}else{
close(sock_fd);
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论