connect应用分析

本文通过C++代码示例介绍了如何设置TCP套接字为非阻塞模式,并展示了不同连接状态下的错误处理方式。通过对连接过程的反复尝试,文章详细记录了连接过程中可能出现的各种错误代码及其含义。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <string.h>
#include <linux/tcp.h>
#include <fcntl.h>
#include <errno.h>
#include <iostream>


int set_no_block(int fd) {
    int flags = fcntl(fd, F_GETFL, 0);
    if(flags == -1) {
        std::cout << "xxx11" << std::endl ;
        return -1 ;
    }


    flags |= O_NONBLOCK;
    if(fcntl(fd, F_SETFL, flags) == -1) {
        std::cout << "xxx12" << std::endl ;
        return -1 ;
    }


    std::cout << "xxx12" << std::endl ;
    return 0 ;
}

int main1(int argc, char** argv) {
    struct sockaddr_in addr_serv ;
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0) ;
    if (sock_fd < 0) {
        std::cout << "xxxx1" << std::endl ;
        return -1 ;
    }


    int n_ret = -1 ;
    n_ret = set_no_block(sock_fd) ;
    if(n_ret != 0) return n_ret ;


    memset(&addr_serv, 0, sizeof(addr_serv)) ;
    addr_serv.sin_family = AF_INET ;
    addr_serv.sin_port = htons(80) ;
    addr_serv.sin_addr.s_addr = inet_addr("183.72.22.99") ;


    int n_cnt = 1000 ;
    int n_115 = 0 ;
    int n_114 = 0 ;
    int n_114_ret_0 = 0 ;
    int n_106 = 0 ;
    while(n_cnt-- > 0) {
        n_ret = connect(sock_fd, (struct sockaddr*)(&addr_serv), sizeof(addr_serv)) ;
        if(n_ret == -1 && errno == 115) ++n_115 ;
else if(n_ret == -1 && errno == 106) ++n_106 ;
        else if(n_ret == 0 && errno == 114) ++n_114_ret_0 ;
        else if(n_ret == -1 && errno == 114) ++n_114 ;
        std::cout << "connect ret:" << n_ret << " errorno:" << errno << " desc:" << strerror(errno) << std::endl ; // one time no block n_ret:-1, errorno:115, desc:Operation now in progress
    }
    std::cout << "count EINPROGRESS(115):" << n_115 << " EALREADY(114):" << n_114 << " EALREADY_ret_0(114):" << n_114_ret_0 << " EISCONN(106):" << n_106 << std::endl ; 
    if(n_ret < 0) {
        close(sock_fd) ;
        std::cout << "xxxx2" << std::endl ;
        return -1 ;
    }

    close(sock_fd) ;
    std::cout << "xxxx3" << std::endl ;
    return 0 ;
}

// connect ret:-1 errorno:115 desc:Operation now in progress

// connect ret:-1 errorno:114 desc:Operation already in progress

// ... 上面重复78 次

// connect ret:0 errorno:114 desc:Operation already in progress
// connect ret:-1 errorno:106 desc:Transport endpoint is already connected

// ... 上面重复 920次

// count EINPROGRESS(115):1 EALREADY(114):78 EALREADY_ret_0(114):1 EISCONN(106):920



int main2(int argc, char** argv) {
    struct sockaddr_in addr_serv ;
    int sock_fd = socket(AF_INET, SOCK_STREAM, 0) ;
    if (sock_fd < 0) {
        std::cout << "xxxx1" << std::endl ;
        return -1 ;
    }


    int n_ret = -1 ;
    //n_ret = set_no_block(sock_fd) ;
    //if(n_ret != 0) return n_ret ;


    memset(&addr_serv, 0, sizeof(addr_serv)) ;
    addr_serv.sin_family = AF_INET ;
    addr_serv.sin_port = htons(80) ;
    addr_serv.sin_addr.s_addr = inet_addr("183.72.22.99") ;


    n_ret = connect(sock_fd, (struct sockaddr*)(&addr_serv), sizeof(addr_serv)) ;
    std::cout << "connect ret:" << n_ret << " errorno:" << errno << " desc:" << strerror(errno) << std::endl ; 
    if(n_ret < 0) {
        close(sock_fd) ;
        std::cout << "xxxx2" << std::endl ;
        return -1 ;
    }


    close(sock_fd) ;
    std::cout << "xxxx3" << std::endl ;
    return 0 ;

}

// connect ret:0 errorno:0 desc:Success



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值