C++socket客户端select异步连接发送接收数据

简介: C++socket客户端select异步连接发送接收数据

这段时间公司项目一直用网口同底层设备交互,顾记录下,具体见代码:

int RFID_STANDARDPROTOCOL_API __stdcall Socket_SendAndRecv(SOCKET Socket, unsigned char * SendBuf
                                                       , unsigned char *RecvBuf, int send_len)
{
    int check_len = send_len - 1;
  int index;
  SendBuf[check_len] = 0;
  for(index = 0; index < check_len; index++)
  {
    SendBuf[check_len] += SendBuf[index];
  }
  SendBuf[check_len] = ~SendBuf[check_len] + 1;
  char recvbuf[1024]={0};
  fd_set fds;
  FD_ZERO(&fds);
  FD_SET(Socket, &fds);
  timeval time_out = {0, 0};
  switch(select(Socket + 1, &fds, NULL, NULL, &time_out))
  {
  case SOCKET_ERROR:
    break;
  case 0:
    break;
  default:
    {
      if (FD_ISSET(Socket, &fds))
      {
        recv(Socket, (char *)recvbuf, 1024, 0);
      }
    }
    break;
  }
  char *sendbuf = (char *)SendBuf;//将 unsigned char* 类型的 SendBuf 强制转换为 char* 类型的 SendBuf
  if(send(Socket, sendbuf, send_len, 0) <= 0)
    return SENDERROR;
  int Lenth = 0;
  HANDLE hEventExit = NULL;
  WSAEVENT EventArray[2] = {WSACreateEvent(), hEventExit};
  WSAEventSelect(Socket, EventArray[0], FD_READ);
  DWORD dwWait = WSAWaitForMultipleEvents(1, EventArray, FALSE, 1000, FALSE);
  if (WAIT_OBJECT_0 == dwWait)
  {
    WSANETWORKEVENTS netEvents;
    if (SOCKET_ERROR == WSAEnumNetworkEvents(Socket, EventArray[0], &netEvents))
    {
      return -1;
    }
    if (!(netEvents.lNetworkEvents & FD_READ) || netEvents.iErrorCode[FD_READ_BIT])
    {
      return -1;
    }
    if((Lenth=recv(Socket, recvbuf, sizeof(recvbuf)-1, 0))<=0)
      return RECVERROR;
  }
  for(index = 0; index < Lenth; index++)
  {
    RecvBuf[index] = (unsigned char)recvbuf[index]; //将 char 类型的 RecvBuf 强制转换为 unsigned  char 类型的 RecvBuf
  }
  if((RecvBuf[0] == 0x0B) && (RecvBuf[3] == 0))
    return SUCCESS;
  else
    return DATAERROR;
}
int RFID_STANDARDPROTOCOL_API __stdcall Socket_ConnectSocket(SOCKET *Socket, char *IPAddress, int Port)
{
    //加载套接字库
  WORD wVersionRequested;
  WSADATA wsaData;
  wVersionRequested = MAKEWORD(1, 1);
  if(WSAStartup(wVersionRequested, &wsaData) != 0)
  {
    return -1;
  }
  if(LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1)
  {
    WSACleanup();
    return -1;
  }
  //创建套接字
  *Socket = socket(AF_INET, SOCK_STREAM, 0);
  if (*Socket == INVALID_SOCKET)
  {
    WSACleanup();
    return -3;
  }
  int TimeOut = 1000;     //设置发送超时2秒
  if(::setsockopt(*Socket,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
  {
  }
  TimeOut = 1000;     //设置接收超时2秒
  if(::setsockopt(*Socket,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
  {
  }
  SOCKADDR_IN addrSrv;
  addrSrv.sin_addr.S_un.S_addr = inet_addr(IPAddress);
  addrSrv.sin_family = AF_INET;
  addrSrv.sin_port = htons(Port);
  //向服务器发送连接请求
#define __NONE_BLOCK_CONN__
  /* 非阻塞式连接 */
#ifdef __NONE_BLOCK_CONN__
  unsigned long mode = 1;
  int iRet = ioctlsocket(*Socket, FIONBIO, &mode);
  if (iRet != NO_ERROR)
  {
  }
  int conn_ret = connect(*Socket, (sockaddr *)&addrSrv, sizeof (sockaddr) );
  mode = 0;
  iRet = ioctlsocket(*Socket, FIONBIO, &mode);
  if (iRet != NO_ERROR)
  {
  }
  TIMEVAL timeval = {0};
  timeval.tv_sec = 0;
  timeval.tv_usec = 950 * 1000;
  fd_set Write, Err;
  FD_ZERO(&Write);
  FD_ZERO(&Err);
  FD_SET(*Socket, &Write);
  FD_SET(*Socket, &Err);
  select(*Socket + 1, NULL, &Write, &Err, &timeval);
  if(FD_ISSET(*Socket, &Write))
  {
    return SUCCESS;
  }
    // /* 阻塞式连接 */
#else
  if (connect(*Socket, (sockaddr *)&addrSrv, sizeof (SOCKADDR_IN) ) == 0)
  {
    return SUCCESS;
  }
#endif
  else
  {
    closesocket(*Socket);
    WSACleanup();
    return -2;
  }
}
相关文章
|
2月前
|
SQL 数据库连接 数据库
在C++的QT框架中实现SQLite数据库的连接与操作
以上就是在C++的QT框架中实现SQLite数据库的连接与操作的基本步骤。这些步骤包括创建数据库连接、执行SQL命令、处理查询结果和关闭数据库连接。在实际使用中,你可能需要根据具体的需求来修改这些代码。
184 14
|
3月前
|
网络协议 开发者 Python
Socket如何实现客户端和服务器间的通信
通过上述示例,展示了如何使用Python的Socket模块实现基本的客户端和服务器间的通信。Socket提供了一种简单且强大的方式来建立和管理网络连接,适用于各种网络编程应用。理解和掌握Socket编程,可以帮助开发者构建高效、稳定的网络应用程序。
133 10
|
3月前
|
监控 API 开发工具
Socket.IO介绍,以及怎么连接测试Socket.IO接口?
Socket.IO 是一个用于浏览器和服务器间实时双向通信的库,支持低延迟消息传递、跨平台运行及自动重连。文章介绍了其特点与调试需求,并详细说明如何使用 Apifox 工具创建、连接、发送/接收 Socket.IO 事件,以及团队协作和调试技巧。掌握这些技能可提升实时应用开发效率与质量。
|
11月前
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
8月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
304 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
8月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
397 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
9月前
|
关系型数据库 MySQL 数据库
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
docker启动mysql多实例连接报错Can’t connect to local MySQL server through socket ‘/var/run/mysqld/mysqld.sock’
486 0
|
10月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
385 0
|
8月前
|
网络协议 测试技术 网络安全
Python编程-Socket网络编程
Python编程-Socket网络编程
78 0
|
11月前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
127 4

热门文章

最新文章