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月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
173 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
2月前
|
JSON 数据格式 Python
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
本文介绍了如何使用Python的socket模块实现客户端到服务器端的文件传输,包括客户端发送文件信息和内容,服务器端接收并保存文件的完整过程。
179 1
Socket学习笔记(一):python通过socket实现客户端到服务器端的文件传输
|
2月前
|
存储 网络协议 Linux
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
聊一聊 Python 的 socket,以及 select、poll、epoll 又是怎么一回事?
167 2
|
3月前
|
关系型数据库 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’
228 0
|
4月前
|
网络协议 数据格式 Python
python Socket无限发送接收数据方式
Socket是指套接字,是对网络中不同主机上的应用进程之间进行双向通信的端点的一种抽象。 一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。
|
4月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
154 0
|
5月前
|
网络协议 Java
如何在Java中使用Socket编程实现TCP连接?
在Java中,通过Socket编程实现TCP连接非常常见。以下演示了基本的TCP通信流程,可根据具体需求进行扩展。
313 0
|
5月前
|
Java 数据格式
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
Java面试题:简述Java Socket编程的基本流程,包括客户端和服务器的创建与通信。
105 0
|
27天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
49 2