当前位置: 首页 > news >正文

C++ Socket通讯连接Server,并可设置连接超时时间

Socket通讯连接Server,并可设置连接超时时间

非阻塞模式:使用 ioctlsocket 将 socket 设置为非阻塞模式,这样 connect 调用不会阻塞主线程。
连接线程:在一个新线程中执行连接操作,使用 std::atomic 来检查连接是否成功。
超时逻辑:主线程使用一个循环来检查连接是否成功,若超出设定的超时时间则退出。


#include <iostream>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <thread>
#include <atomic>#pragma comment(lib, "ws2_32.lib")void ThreadConnect(SOCKET sock, struct sockaddr_in* server, std::atomic<bool>& connected)
{if (connect(sock, (struct sockaddr*)server, sizeof(*server)) == SOCKET_ERROR){connected = false;}else{connected = true;}
}bool ConnectServer()
{WSADATA wsaData;SOCKET sock;struct sockaddr_in server;// 初始化 Winsockif (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0){std::cerr << "Failed to initialize Winsock. Error: " << WSAGetLastError() << std::endl;return false;}// 创建 socketsock = socket(AF_INET, SOCK_STREAM, 0);if (sock == INVALID_SOCKET){std::cerr << "Could not create socket. Error: " << WSAGetLastError() << std::endl;WSACleanup();return false;}// 设置 socket 为非阻塞模式u_long mode = 1; // 1 表示非阻塞模式ioctlsocket(sock, FIONBIO, &mode);// 配置服务器地址server.sin_family = AF_INET;server.sin_port = htons(7999); // 服务器端口inet_pton(AF_INET, "127.0.0.1", &server.sin_addr); // 服务器地址std::atomic<bool> connected(false);std::thread connectThread(ThreadConnect, sock, &server, std::ref(connected));// 等待连接或超时int connecTimeout = 1000;DWORD startTime = GetTickCount();while (GetTickCount() - startTime < connecTimeout){if (connected){break;}Sleep(100);}   connectThread.join(); // 关闭连接线程std::cout << "Connection time: " << (GetTickCount() - startTime) << " ms" << std::endl;if (!connected){std::cerr << "Connection timeout." << std::endl;closesocket(sock);WSACleanup();return false;}mode = 0; // 设置为阻塞模式ioctlsocket(sock, FIONBIO, &mode);std::cout << "Connected to server!" << std::endl;int sendTimeout = 1000; // 发送超时设置int recvTimeout = 1000; // 接收超时设置if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&sendTimeout, sizeof(sendTimeout)) < 0){std::cerr << "Failed to set send timeout. Error: " << WSAGetLastError() << std::endl;closesocket(sock);WSACleanup();return false;}if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&recvTimeout, sizeof(recvTimeout)) < 0){std::cerr << "Failed to set receive timeout. Error: " << WSAGetLastError() << std::endl;closesocket(sock);WSACleanup();return false;}// 这里可以添加发送和接收数据的代码// 关闭 socketclosesocket(sock);WSACleanup();return true;
}int main()
{ConnectServer();std::cin.get();return 0;
}

http://www.mrgr.cn/news/54167.html

相关文章:

  • 了解袜卡产品
  • Pytorch常用函数汇总【持续更新】
  • linux file结构体与inode结构体
  • Spring Boot配置文件不识别变量的解决方案
  • leetcode22.括号生成
  • 云原生介绍
  • 2060:【例1.1】计算机输出
  • 【Java】—一篇搞懂POJO和VO、BO、DTO、PO模型
  • 程序员是否要考研?结合当前环境和形势的分析
  • linux线程 | 全面理解同步与互斥 | 同步
  • SpringBoot配置文件敏感信息如何加密?及踩坑总结(全面讲解)
  • 【Python爬虫实战】深入解析BeautifulSoup4的强大功能与用法
  • JavaScript 字符串常用方法
  • USART串口(发送和接收)
  • 【MySQL】多表查询——内连接,左/右连接
  • MyBatisPlus
  • 【算法】将单向链表按某值分成左边小、中间相等、右边大的形式
  • 在各大媒体报纸上刊登自己的文章用什么投稿方法发表快?
  • RDK X5 目标跟踪核心代码Deepsort
  • Flux.concat 使用说明书
  • 注塑机机械手升降传送机程序
  • 现代大数据架构Kappa
  • 【Java】—JavaBean转换方法详解
  • 数据结构练习题4(链表)
  • 网络空间安全之一个WH的超前沿全栈技术深入学习之路(二:渗透测试行业术语扫盲)作者——LJS
  • 单位评职称需要在指定媒体上投稿发表文章看我如何轻松应对