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 Connect( const 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::Connect( const char * sIP, short iPort, struct timeval * pTV ){m_sIP = sIP;m_iPort = iPort;m_iSock = socket(AF_INET, SOCK_STREAM, IPPROTO_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_SOCKET, SO_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, NULL, NULL, &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;}
阅读全文
0 0
- NBSocket
- /dev/fb0入门练习
- 二叉树非递归版的后序遍历算法
- 还原SQL Server数据库
- 每日一练(20171025)
- ViewPager+TimerTask实现Gallery画廊效果
- NBSocket
- [java]日期工具类-DateUtil
- (DT系列一)DTS结构及其编译方法
- WordPress主题开发:设置和获取浏览次数
- pomelo(六) 中文FAQ
- ubuntu 安装nvidia 驱动后无法进入桌面(循环进入登录界面 )
- Rust: flat_map,filter_map,for_each
- easyui的datagrid的右侧区域空白及列数横向不能填满
- php获取一个目录下的所有文件全路径---包括子目录---并存放到一维数组