⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ecostestsocket.cpp

📁 eCos1.31版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//####COPYRIGHTBEGIN####//                                                                          // ----------------------------------------------------------------------------// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.//// This program is part of the eCos host tools.//// This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version.// // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for // more details.// // You should have received a copy of the GNU General Public License along with// this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.//// ----------------------------------------------------------------------------//                                                                          //####COPYRIGHTEND####//=================================================================////        eCosTestSocket.cpp////        Socket test class////=================================================================//=================================================================//#####DESCRIPTIONBEGIN####//// Author(s):     sdf// Contributors:  sdf// Date:          1999-04-01// Description:   This class abstracts tcp/ip sockets for use in the testing infrastructure// Usage:////####DESCRIPTIONEND#####include "eCosStd.h"#include "eCosTestSocket.h"#include "eCosTestSerial.h"#include "eCosTrace.h"enum {ERR_TIMEOUT=20000, ERR_READ_AFTER_CLOSE=20001};// Blocking read on one or other of the data sources:// Result:  0 - error occurred//          1 - data read from socket//          2 - data read from serialint CeCosTestSocket::SSRead (CeCosTestSerial &serial,CeCosTestSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop){    int rc=0;    bool bBlocking=serial.GetBlockingReads();    bool bBlockingModified=false;    while(0==pbStop || !(*pbStop)){        if(!socket.Peek(nRead)){            break;        } else if(nRead){            nRead=MIN(nRead,nSize);            rc=socket.recv(pBuf,nRead)?1:0;            break;        } else {            if(bBlocking){                serial.SetBlockingReads(false);                bBlockingModified=true;                bBlocking=false;            }            if(serial.Read(pBuf,nSize,nRead)){                if(nRead>0){                    rc=2;                    break;                }            } else {                break;            }        }        Sleep(1);    }    if(bBlockingModified){        serial.SetBlockingReads(true);    }    return rc;}// ctors and dtorsCeCosTestSocket::CeCosTestSocket ():    m_nDefaultTimeout(10*1000),	m_nSock(-1),    m_nClient(0){    TRACE(_T("Create socket instance %08x\n"),(unsigned int)this);}CeCosTestSocket::CeCosTestSocket (int sock /*result of previous call of Listen*/, bool *pbStop):    m_nDefaultTimeout(10*1000),	m_nSock(-1),    m_nClient(0){    TRACE(_T("Create socket instance %08x\n"),(unsigned int)this);    Accept(sock,pbStop);}CeCosTestSocket::CeCosTestSocket (String strHost,int port,Duration dTimeout):    m_nDefaultTimeout(10*1000),	m_nSock(-1),    m_nClient(0){    TRACE(_T("Create socket instance %08x\n"),(unsigned int)this);    Connect(strHost,port,dTimeout);}bool CeCosTestSocket::Accept(int sock /*result of previous call of Listen*/, bool *pbStop){    m_nSock=-1;    while(0==pbStop||!*pbStop){        struct sockaddr cli_addr;        #ifndef _WIN32        unsigned         #endif	    int clilen=sizeof(struct sockaddr);        m_nSock=::accept(sock, (struct sockaddr *) &cli_addr, &clilen);        SaveError();        if(-1==m_nSock){             if(WOULDBLOCK==SocketError()){                Sleep(100);                continue;            }        } else {            memcpy(&m_nClient,cli_addr.sa_data+2,4);            TRACE(_T("Connection accepted from %s - socket %d\n"),(LPCTSTR )ClientName(m_nClient),m_nSock);            SetSocketOptions();            break;        }	}     return -1!=m_nSock;}int CeCosTestSocket::Listen(int nTcpPort){   // Create socket    int sock=::socket(AF_INET, SOCK_STREAM, 0);    if (sock == -1) {        ERROR(_T("Couldn't create socket\n"));    } else {        TRACE(_T("Created socket %d listening on port %d\n"),sock,nTcpPort);        // Bind socket to address        struct sockaddr_in serv_addr;        memset(&serv_addr, 0, sizeof serv_addr);        serv_addr.sin_family = AF_INET;        serv_addr.sin_port=htons((short)nTcpPort);        serv_addr.sin_addr.s_addr = INADDR_ANY;                if (::bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {            TRACE(_T("Couldn't bind socket on port %d\n"),nTcpPort);            CloseSocket(sock);        } else if (-1==::listen(sock, SOMAXCONN)){            CloseSocket(sock);            TRACE(_T("socket error on listen - port %d\n"),nTcpPort);        } else {	        #ifdef _WIN32            int nTrue=1;            bool rc=(0==::ioctlsocket(sock, FIONBIO, (unsigned long *)&nTrue));	        #else //UNIX            int flags=::fcntl(sock,F_GETFL);	          flags|=O_NONBLOCK;            bool rc=(0==::fcntl (sock, F_SETFL, flags));	        #endif	        if(!rc){                TRACE(_T("Failed to set socket options on socket %d\n"),sock);            }        }    }    return sock;}bool CeCosTestSocket::Connect(String strHost,int port,Duration dTimeout){    dTimeout=TimeoutDuration(dTimeout);    struct sockaddr_in serv_addr;    struct hostent* host_dat;    char ip[16]; // for nnn.nnn.nnn.nnn    VTRACE(_T("Connect: %s:%d timeout=%d\n"),(LPCTSTR )strHost,port,dTimeout);    // Get the target host address    String strErr;    char *pszHost=strHost.GetCString();    if (0==(host_dat=::gethostbyname(pszHost))){        SaveError();        TRACE(_T("Could not get IP address for host %s - %s\n"),(LPCTSTR )strHost,(LPCTSTR )SocketErrString());    } else {        char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] )  );        if(0==c){            SaveError();            TRACE(_T("Could inet_ntoa %s - %s\n"),(LPCTSTR )strHost,(LPCTSTR )SocketErrString());        } else {            strcpy(ip, c);            memset(&serv_addr, 0, sizeof serv_addr);            // Create socket            m_nSock = ::socket(AF_INET, SOCK_STREAM, 0);            if (-1 == m_nSock) {                TRACE(_T("Could not create socket [%s:%d]\n"),(LPCTSTR )strHost,port);            } else {                #ifdef _WIN32                SetSocketOptions();                #endif                TRACE(_T("Created socket %d connected to %s:%d\n"),m_nSock,(LPCTSTR )strHost,port);                // Bind socket to address                serv_addr.sin_family = AF_INET;                serv_addr.sin_port=htons((short)port);                SaveError();                serv_addr.sin_addr.s_addr = inet_addr(ip);                // Connect to server                VTRACE(_T("Connect() : connecting to server\n"));                int cc=::connect(m_nSock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));                SaveError();                String strMsg;                if(-1==cc){                    if(    #ifdef _WIN32                       WOULDBLOCK==SocketError()    #else // UNIX                       EINPROGRESS==SocketError()    #endif                       ){                        // Allow dTimeout milliseconds for connect to complete                        fd_set set;                        FD_ZERO(&set);    #ifdef _WIN32                        #pragma warning( push )                        #pragma warning( disable : 4127 ) // conditional expression is constant    #endif                        FD_SET((unsigned)m_nSock, &set);    #ifdef _WIN32                        #pragma warning( pop )    #endif                        struct timeval tv;                        tv.tv_sec = dTimeout/1000;                          tv.tv_usec = 1000*(dTimeout % 1000);                        switch(::select(m_nSock, NULL, &set , NULL, &tv)){                            case 0:                                m_nErr=ERR_TIMEOUT;                                strMsg.Format(_T("attempt timed out after %d seconds"),dTimeout/1000);                                break;                            case -1:                                SaveError();                                strMsg=SocketErrString();                                break;                            default:                                cc=0;                        }                    } else {                        strMsg=SocketErrString();                    }                }                if(-1==cc){                    TRACE(_T("Could not connect to %s:%d - %s\n"),(LPCTSTR )strHost,port,(LPCTSTR )strMsg);                    CloseSocket(m_nSock);                }  else {                    #ifndef _WIN32                    SetSocketOptions();                    #endif                }            }        }    }    delete [] pszHost;    return -1!=m_nSock;}bool CeCosTestSocket::sendrecv(bool bSend,const void *pData,unsigned int nLength,	LPCTSTR pszMsg,Duration dTimeout,CeCosTestSocket::StopFunc pFnStop,void *pParam){      dTimeout=TimeoutDuration(dTimeout);    LPCTSTR pszSR=(bSend?_T("sending"):_T("receiving"));  LPTSTR c=(LPTSTR )pData;  Time ft0=Now();  int nTodo=nLength;  while((nTodo>0) && ((0==pFnStop) || (!pFnStop(pParam)))){    int s=bSend?::send(m_nSock, (const char *)c, nTodo, 0): ::recv(m_nSock, (char *)c, nTodo, 0);    if(0==s && !bSend){      m_nErr=ERR_READ_AFTER_CLOSE;    } else {      SaveError();    }    if(-1==s && WOULDBLOCK==SocketError()){      Duration d=Duration(Now()-ft0);      if(d>dTimeout){        TRACE(_T("%d/%d mSec timeout on socket %d %s %s - processed %d/%d bytes\n") ,          d,dTimeout,m_nSock,pszSR,pszMsg,           nLength-nTodo,nLength);        m_nErr=ERR_TIMEOUT;        break;      }      Sleep(100);    } else if (s>0) {      c+=s;      nTodo-=s;      ft0=Now();    } else {      TRACE(_T("Error on socket %d %s %s - %s\n") ,m_nSock, pszSR, pszMsg, (LPCTSTR )SocketErrString());      break;    }  }  return 0==nTodo;}// Graceful socket closedownCeCosTestSocket::~CeCosTestSocket(){	Close();    TRACE(_T("Delete socket instance %08x\n"),(unsigned int)this);}bool CeCosTestSocket::CloseSocket(int &sock){    bool rc=false;    if(-1!=sock){        TRACE(_T("Closing socket %d\n"),sock);        try{            shutdown(sock,0);// SD_BOTH    #ifdef _WIN32            rc=(0==closesocket(sock));    #else // UNIX            rc=(0==close(sock));    #endif        }        catch(...) {            TRACE(_T("!!! Exception caught in CeCosTestSocket::CloseSocket!!!\n"));        }        sock=-1;    }	return rc;}bool CeCosTestSocket::SetSocketOptions(){    bool rc;    #ifdef _WIN32      int nTrue=1;      rc=(0==::ioctlsocket(m_nSock, FIONBIO, (unsigned long *)&nTrue));      SaveError();    #else // UNIX      int flags=::fcntl(m_nSock,F_GETFL);      SaveError();      flags|=O_NONBLOCK;      rc=(0==::fcntl (m_nSock, F_SETFL, flags));      SaveError();    #endif    //LINGER linger;    //setsockopt(m_nSock,SOL_SOCKET,SO_LINGER,(LPCTSTR )linger, sizeof(LINGER));	if(!rc){        TRACE(_T("Failed to set socket options socket %d - %s\n"),m_nSock,(LPCTSTR )SocketErrString());    }    return rc;}String CeCosTestSocket::SocketErrString(int nErr){    String str;    #ifdef _WIN32      switch(nErr){        case ERR_TIMEOUT: str=_T("Read operation timed out");break;        case ERR_READ_AFTER_CLOSE: str=_T("Read operation after socket closed");break;        case WSAEACCES: str=_T("Permission denied");break;        case WSAEADDRINUSE: str=_T("Address already in use");break;        case WSAEADDRNOTAVAIL: str=_T("Cannot assign requested address");break;        case WSAEAFNOSUPPORT: str=_T("Address family not supported by protocol family");break;        case WSAEALREADY: str=_T("Operation already in progress");break;        case WSAECONNABORTED: str=_T("Software caused connection abort");break;        case WSAECONNREFUSED: str=_T("Connection refused");break;        case WSAECONNRESET: str=_T("Connection reset by peer");break;        case WSAEDESTADDRREQ: str=_T("Destination address required");break;        case WSAEFAULT: str=_T("Bad address");break;        case WSAEHOSTDOWN: str=_T("Host is down");break;        case WSAEHOSTUNREACH: str=_T("No route to host");break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -