您的位置:首页 > 编程语言 > C语言/C++

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

2016-12-09 14:32 435 查看
这段时间公司项目一直用网口同底层设备交互,顾记录下,具体见代码:

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;
}
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: