TCP 网络超时 select 及 recv 实现

fd_set set;
    struct timeval st_time;
    
    st_time.tv_sec  = 3 * 3;
    st_time.tv_usec = 0;

    while (1)  
    {   
        strcpy(sendbuf, "hello every");

        FD_ZERO(&set);
        FD_SET(sock_cli, &set);
     
        printf("before select. \n");
        int ret = select(sock_cli + 1, &set, (fd_set *)0, (fd_set *)0, &st_time);
        if (ret == 0)
        {   
            printf("select timeout.\n");
        }   
        else if (ret < 0)
        {   
            printf("select error.\n");
            break;
        }   
        else if (ret == 1)
        {   
            if (FD_ISSET(sock_cli, &set))
            {   
                ret = recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收  
                if (ret <= 0)
                {   
                    printf("server disconnect..\n");
                    break;
                }   
            }   
        }   

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++实现网络通讯,可以使用操作系统提供的socket库。下面是一个简单的示例代码,支持TCP协议和异步通信: ```c++ #include <iostream> #include <string> #include <thread> #include <chrono> #include <cstring> #include <cstdlib> #include <cstdio> #include <cerrno> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/socket.h> #include <fcntl.h> #include <unistd.h> const int BUFFER_SIZE = 1024; // 缓冲区大小 void error_handling(const char* message) { perror(message); exit(1); } int create_socket() { int sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock == -1) { error_handling("socket() error"); } return sock; } void set_nonblock(int sock) { int flag = fcntl(sock, F_GETFL, 0); if (flag == -1) { error_handling("fcntl(F_GETFL) error"); } if (fcntl(sock, F_SETFL, flag | O_NONBLOCK) == -1) { error_handling("fcntl(F_SETFL, O_NONBLOCK) error"); } } int connect_server(int sock, const char* ip, int port) { struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr(ip); server_addr.sin_port = htons(port); int ret = connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)); if (ret == -1) { if (errno == EINPROGRESS) { // 连接正在进行 std::cout << "connecting..." << std::endl; fd_set write_fds; FD_ZERO(&write_fds); FD_SET(sock, &write_fds); int max_fd = sock + 1; struct timeval timeout; timeout.tv_sec = 5; // 超时时间为5秒 timeout.tv_usec = 0; if (select(max_fd, nullptr, &write_fds, nullptr, &timeout) == -1) { error_handling("select() error"); } if (!FD_ISSET(sock, &write_fds)) { error_handling("connection timeout"); } } else { error_handling("connect() error"); } } std::cout << "connect success" << std::endl; return 0; } void recv_data(int sock) { char buffer[BUFFER_SIZE]; while (true) { memset(buffer, 0, BUFFER_SIZE); int ret = recv(sock, buffer, BUFFER_SIZE - 1, 0); if (ret == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { // 没有数据可读 std::this_thread::sleep_for(std::chrono::milliseconds(100)); continue; } else { error_handling("recv() error"); break; } } else if (ret == 0) { // 连接被断开 std::cout << "connection closed by server" << std::endl; break; } else { std::cout << "recv: " << buffer << std::endl; } } } void send_data(int sock) { std::string message; char buffer[BUFFER_SIZE]; while (true) { std::getline(std::cin, message); if (message == "exit") { break; } memset(buffer, 0, BUFFER_SIZE); strncpy(buffer, message.c_str(), message.size()); int ret = send(sock, buffer, message.size(), 0); if (ret == -1) { error_handling("send() error"); break; } } } int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <IP> <port>" << std::endl; return 1; } int sock = create_socket(); set_nonblock(sock); connect_server(sock, argv[1], std::atoi(argv[2])); std::thread t1(recv_data, sock); std::thread t2(send_data, sock); t1.join(); t2.join(); close(sock); return 0; } ``` 上述代码中,我们使用socket函数创建了一个TCP协议的套接字,然后使用fcntl函数将该套接字设置成非阻塞模式。在connect时,如果连接正在进行中,则使用select函数等待连接完成,超时时间为5秒。接着,我们使用两个线程分别处理接收数据和发送数据的任务,实现了异步通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值