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

📄 ecossocket.cpp

📁 移植到WLIT项目的redboot源代码
💻 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####//=================================================================////        eCosSocket.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 "eCosSocket.h"#include "eCosSerial.h"#include "eCosThreadUtils.h"#include "eCosTrace.h"#include <map>enum {ERR_TIMEOUT=20000, ERR_READ_AFTER_CLOSE=20001};// Blocking read on one or other of the data sources:// Result:  -1 - socket error occurred//           1 - data read from socket//          -2 - serial error occurred//           2 - data read from serialCeCosSocket::SSReadResult CeCosSocket::SSRead (CeCosSerial &serial,CeCosSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead,bool *pbStop){  SSReadResult rc=SS_STOPPED;  bool bBlocking=serial.GetBlockingReads();  bool bBlockingModified=false;  while(0==pbStop || !(*pbStop)){    if(!socket.Peek(nRead)){      rc=SS_SOCKET_ERROR;      break;    } else if(nRead){      nRead=MIN(nRead,nSize);      rc=socket.recv(pBuf,nRead)?SS_SOCKET_READ:SS_SOCKET_ERROR;      break;    } else {      if(bBlocking){        serial.SetBlockingReads(false);        bBlockingModified=true;        bBlocking=false;      }      if(serial.Read(pBuf,nSize,nRead)){        if(nRead>0){          rc=SS_SERIAL_READ;          break;        }      } else {        rc=SS_SERIAL_ERROR;        break;      }    }    CeCosThreadUtils::Sleep(10);  }  if(bBlockingModified){    serial.SetBlockingReads(true);  }  return rc;}// ctors and dtorsCeCosSocket::CeCosSocket ():m_nDefaultTimeout(10*1000),m_nSock(-1),m_nClient(0){  VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this);}CeCosSocket::CeCosSocket (int sock /*result of previous call of Listen*/, bool *pbStop):m_nDefaultTimeout(10*1000),m_nSock(-1),m_nClient(0){  VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this);  Accept(sock,pbStop);}CeCosSocket::CeCosSocket (LPCTSTR pszHostPort,Duration dTimeout):m_nDefaultTimeout(10*1000),m_nSock(-1),m_nClient(0){  VTRACE(_T("Create socket instance %08x\n"),(unsigned int)this);  Connect(pszHostPort,dTimeout);}bool CeCosSocket::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()){        CeCosThreadUtils::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 CeCosSocket::Listen(int nTcpPort){  // Create socket  int sock=::socket(AF_INET, SOCK_STREAM, 0);  if (sock == -1) {    ERROR(_T("Couldn't create socket\n"));  } else {    VTRACE(_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 CeCosSocket::Connect(LPCTSTR pszHostPort,Duration dTimeout){  dTimeout=TimeoutDuration(dTimeout);  struct sockaddr_in serv_addr;    VTRACE(_T("Connect: %s timeout=%d\n"),pszHostPort,dTimeout);    // Get the target host address  String strHost;  int nPort;  CeCosSocket::ParseHostPort(pszHostPort,strHost,nPort);  String strErr;  char *ip=GetHostByName(strHost).GetCString();  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]\n"),pszHostPort);  } else {#ifdef _WIN32    SetSocketOptions();#endif    VTRACE(_T("Created socket %d connected to %s\n"),m_nSock,pszHostPort);    // Bind socket to address    serv_addr.sin_family = AF_INET;    serv_addr.sin_port=htons((short)nPort);    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 - %s\n"),pszHostPort,(LPCTSTR)strMsg);      CloseSocket(m_nSock);    }  else {#ifndef _WIN32      SetSocketOptions();#endif    }  }  delete [] ip;  return -1!=m_nSock;}bool CeCosSocket::sendrecv(bool bSend,const void *pData,unsigned int nLength,                           LPCTSTR pszMsg,Duration dTimeout,CeCosSocket::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;      }      CeCosThreadUtils::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 closedownCeCosSocket::~CeCosSocket(){  Close();  VTRACE(_T("Delete socket instance %08x\n"),(unsigned int)this);}bool CeCosSocket::CloseSocket(int &sock){  bool rc=false;  if(-1!=sock){    VTRACE(_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 CeCosSocket::CloseSocket!!!\n"));    }    sock=-1;  }  return rc;}bool CeCosSocket::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  int bLinger=0;  setsockopt(m_nSock,SOL_SOCKET,SO_LINGER,(const char *)&bLinger, sizeof(bLinger));  if(!rc){    TRACE(_T("Failed to set socket options socket %d - %s\n"),m_nSock,(LPCTSTR )SocketErrString());  }  return rc;}String CeCosSocket::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;  case WSAEINPROGRESS: str=_T("Operation now in progress");break;  case WSAEINTR: str=_T("Interrupted function call");break;  case WSAEINVAL: str=_T("Invalid argument");break;  case WSAEISCONN: str=_T("Socket is already connected");break;  case WSAEMFILE: str=_T("Too many open files");break;  case WSAEMSGSIZE: str=_T("Message too long");break;  case WSAENETDOWN: str=_T("Network is down");break;  case WSAENETRESET: str=_T("Network dropped connection on reset");break;  case WSAENETUNREACH: str=_T("Network is unreachable");break;  case WSAENOBUFS: str=_T("No buffer space available");break;  case WSAENOPROTOOPT: str=_T("Bad protocol option");break;  case WSAENOTCONN: str=_T("Socket is not connected");break;  case WSAENOTSOCK: str=_T("Socket operation on non-socket");break;  case WSAEOPNOTSUPP: str=_T("Operation not supported");break;  case WSAEPFNOSUPPORT: str=_T("Protocol family not supported");break;  case WSAEPROCLIM: str=_T("Too many processes");break;  case WSAEPROTONOSUPPORT: str=_T("Protocol not supported");break;  case WSAEPROTOTYPE: str=_T("Protocol wrong type for socket");break;  case WSAESHUTDOWN: str=_T("Cannot send after socket shutdown");break;  case WSAESOCKTNOSUPPORT: str=_T("Socket type not supported");break;  case WSAETIMEDOUT: str=_T("Connection timed out");break;  case WSATYPE_NOT_FOUND: str=_T("Class type not found");break;  case WSAEWOULDBLOCK: str=_T("Resource temporarily unavailable");break;  case WSAHOST_NOT_FOUND: str=_T("Host not found");break;  case WSA_INVALID_HANDLE: str=_T("Specified event object handle is invalid");break;  case WSA_INVALID_PARAMETER: str=_T("One or more parameters are invalid");break;    //case WSAINVALIDPROCTABLE: str=_T("Invalid procedure table from service provider");break;

⌨️ 快捷键说明

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