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;
  }
}
相关文章
|
21天前
|
网络协议 程序员 Python
pythonTCP客户端编程创建Socket对象
【4月更文挑战第6天】本教程介绍了TCP客户端如何创建Socket对象。Socket作为网络通信的基础单元,包含协议、IP地址和端口等信息。在TCP/IP中,Socket分为流式(TCP)、数据报(UDP)和原始套接字。以Python为例,创建TCP Socket对象需调用`socket.socket(AF_INET, SOCK_STREAM)`。为确保健壮性,应使用异常处理处理可能的`socket.error`。学习本教程将帮助你掌握TCP客户端创建Socket对象的技能。
|
1月前
|
存储 并行计算 前端开发
【C++ 函数 基础教程 第五篇】C++深度解析:函数包裹与异步计算的艺术(二)
【C++ 函数 基础教程 第五篇】C++深度解析:函数包裹与异步计算的艺术
39 1
|
1月前
|
数据安全/隐私保护 C++ 容器
【C++ 函数 基础教程 第五篇】C++深度解析:函数包裹与异步计算的艺术(一)
【C++ 函数 基础教程 第五篇】C++深度解析:函数包裹与异步计算的艺术
47 0
|
1月前
|
数据处理 C# C++
如何使用C#和C++结构体实现Socket通信
如何使用C#和C++结构体实现Socket通信
|
16天前
|
存储 算法 Linux
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
【实战项目】网络编程:在Linux环境下基于opencv和socket的人脸识别系统--C++实现
40 6
|
12天前
|
网络协议 Ubuntu Unix
Linux 下使用 socket 实现 TCP 客户端
Linux 下使用 socket 实现 TCP 客户端
|
13天前
|
安全 程序员
|
1月前
|
Unix Linux C++
【C/C++ 造轮子】Linux异步计时器:深入探讨和应用 (Linux Asynchronous Timers: An In-depth Exploration and Application)
【C/C++ 造轮子】Linux异步计时器:深入探讨和应用 (Linux Asynchronous Timers: An In-depth Exploration and Application)
60 1
|
1月前
|
存储 网络协议 Java
【TCP 连接手段】C++编程视角下的TCP:短连接与长连接深度解析
【TCP 连接手段】C++编程视角下的TCP:短连接与长连接深度解析
59 1
|
2月前
|
C++
C++实现Socket连接通信
C++实现Socket连接通信
13 1