NBSocket

来源:互联网 发布:tpp ttip 知乎 编辑:程序博客网 时间:2024/05/17 13:10
#ifndef _NBSOCKET_H_#define _NBSOCKET_H_ #include<winsock2.h>#include<string>#include"Channel.h" class NBSocket{public:NBSocket();~NBSocket(); int Connectconst char * sIP, short iPort, struct timeval * pTV = NULL );int Send(  char * pBuffer, int iLen );int Recv( ); void SetChannel( Channel * pChannel ){m_pChannel = pChannel;} private:SOCKET m_iSock;Channel * m_pChannel;std::string m_sIP;int m_iPort;}; #endif

#include "stdafx.h"#include "NBSocket.h"#include "util.hpp"#include <iostream> using namespace std; NBSocket::NBSocket() : m_iSock(INVALID_SOCKET),m_pChannel(NULL){} NBSocket::~NBSocket(){if ( m_iSock != INVALID_SOCKET ){closesocket( m_iSock );}} int NBSocket::Connectconst char * sIP, short iPort, struct timeval * pTV ){m_sIP = sIP;m_iPort = iPort;m_iSock = socket(AF_INETSOCK_STREAMIPPROTO_TCP);if ( m_iSock == INVALID_SOCKET ){cout<< __FUNCTION__<<":Create Socket Failed::"<<GetLastError()<<endl;return -1;} unsigned long on = 1;SetNonBlock(  m_iSock, on ); struct sockaddr_in ServerAddr;ServerAddr.sin_family = AF_INET;ServerAddr.sin_addr.s_addr = inet_addr( sIP);ServerAddr.sin_port = htons( iPort );memset(ServerAddr.sin_zero, 0x00, 8); int iRet =  connect( m_iSock, (SOCKADDR*)&ServerAddr, sizeof(SOCKADDR));if ( iRet == 0 ){return 0;}else if ( iRet == -1 && errno != EINPROGRESS ){fd_set Readset;FD_ZERO(&Readset);  FD_SET(m_iSock, &Readset);  iRet = select( -1, NULL, &Readset, NULL,  pTV );if (  iRet <  0 )  {cout<< __FUNCTION__<<":select Failed:"<<GetLastError()<<endl;return -2;}else if ( iRet == 0 ){// timeout cout<< __FUNCTION__<<": connect timeout :"<<GetLastError() << ".sIP:"<< sIP << ",iPort:" << iPort <<endl;return -2;}else{  int error = -1;  int optLen = sizeof(int);  getsockopt( m_iSock, SOL_SOCKETSO_ERROR, (char*)&error, &optLen);    if ( 0 != error ){  cout<< __FUNCTION__<<":get socket error:"<<GetLastError()<<endl;return -3;} char on = 1;SetNoDelay( m_iSock, on );  linger stLinger;stLinger.l_onoff = 1;stLinger.l_linger = 0;SetLinger( m_iSock, stLinger ); }}else{return -1;} return 0;} int NBSocket::Send(  char * pBuffer, int iLen ){if ( m_iSock == - 1 ){cout <<  __FUNCTION__ << ":m_iSock is invalid.reconnect:" << m_sIP << ":" << m_iPort << endl;int iRet = Connect(  m_sIP.c_str(), m_iPort );if ( iRet != 0 ){return -1;}} struct timeval  stTV;stTV.tv_sec = 3;stTV.tv_usec = 0; int iTotalSend = 0;while ( true ){fd_set WriteSet;FD_ZERO(&WriteSet);  FD_SET(m_iSock, &WriteSet);   int iRet = select( -1, NULL, &WriteSet, NULL,  &stTV );if ( iRet <= 0 )  {cout<< __FUNCTION__ << ":select Failed:"<<GetLastError()<<endl;return -1;}else if (  iRet == 0 )  {cout<< __FUNCTION__ << ": send timeout :"<<GetLastError()<<endl;return -1;}else if  ( FD_ISSET( m_iSock, &WriteSet ) ){int iCurSend = send( m_iSock,  pBuffer + iTotalSend, iLen - iTotalSend,  0 );if ( iCurSend  == -1 ){int iError = GetLastError();if ( iError == WSAEWOULDBLOCK ){continue;}else{cout << __FUNCTION__<< ":send failed:" <<  iError  << endl;closesocket( m_iSock );m_iSock = -1;return -2;}}else{iTotalSend += iCurSend;if ( iTotalSend == iLen ){break;}}}}return iTotalSend;}  int NBSocket::Recv(){if ( m_iSock == - 1 ){cout <<  __FUNCTION__ << ":m_iSock is invalid. reconnect " << m_sIP << ":" << m_iPort<< endl;int iRet = Connect(  m_sIP.c_str(), m_iPort );if ( iRet != 0 ){return -1;}} string sRecvBuffer;int iBufferLen = 16384;sRecvBuffer.reserve( iBufferLen );char   pBuffer[16384]; struct timeval  stTV;stTV.tv_sec = 10;stTV.tv_usec = 0; while ( true ){fd_set ReadSet;FD_ZERO(&ReadSet);  FD_SET(m_iSock, &ReadSet);  int iRet = select( -1, &ReadSet, NULLNULL,  &stTV );if (  iRet <  0 )  {cout<< __FUNCTION__ << ":select Failed:"<<GetLastError()<<endl;return -1;}else if (  iRet  ==  0 )  {//cout<< __FUNCTION__ << ": recv timeout :"<<GetLastError()<<endl;return 0;}else if  ( FD_ISSET( m_iSock, &ReadSet ) ){// recv 一直到EWOULDBLOCKwhile ( true ){int iCurRecv = recv( m_iSock,  pBuffer,  iBufferLen,  0 );//cout << "recv  return :" <<  iCurRecv  << endl;if ( iCurRecv == -1 ){//cout << __FUNCTION__<< ":recv  got error:" <<  GetLastError() << endl;int iError = GetLastError();if ( iError == WSAEWOULDBLOCK ){break;}else{cout << __FUNCTION__<< ":recv failed:" <<  iError << endl;closesocket( m_iSock );m_iSock = -1;return -2;}}else if ( iCurRecv > 0 ){sRecvBuffer.append( pBuffer, iCurRecv );}else{cout << "recv return 0, server has close this socket, just return " << endl;closesocket( m_iSock );m_iSock = -1;return -3;}} if ( !sRecvBuffer.empty() ){m_pChannel->ProcessStream(  sRecvBuffer.data(), sRecvBuffer.length() );sRecvBuffer.clear();return 0;}}} return -1;}     

原创粉丝点击