URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [host/] [tools/] [Utils/] [common/] [eCosSocket.cpp] - Rev 786
Compare with Previous | Blame | View Log
// ####ECOSHOSTGPLCOPYRIGHTBEGIN#### // ------------------------------------------- // This file is part of the eCos host tools. // Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. // // 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 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., 51 Franklin Street, // Fifth Floor, Boston, MA 02110-1301, USA. // ------------------------------------------- // ####ECOSHOSTGPLCOPYRIGHTEND#### //================================================================= // // 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 serial CeCosSocket::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 dtors CeCosSocket::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 closedown CeCosSocket::~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; //case WSAINVALIDPROVIDER: str=_T("Invalid service provider version number");break; case WSA_IO_INCOMPLETE: str=_T("Overlapped I/O event object not in signaled state");break; case WSA_IO_PENDING: str=_T("Overlapped operations will complete later");break; case WSA_NOT_ENOUGH_MEMORY: str=_T("Insufficient memory available");break; case WSANOTINITIALISED: str=_T("Successful case WSAStartup not yet:performed");break; case WSANO_DATA: str=_T("Valid name, no data record of requested type");break; case WSANO_RECOVERY: str=_T("This is a non-recoverable error");break; //case WSAPROVIDERFAILEDINIT: str=_T("Unable to initialize a service provider");break; case WSASYSCALLFAILURE: str=_T("System call failure");break; case WSASYSNOTREADY: str=_T("Network subsystem is unavailable");break; case WSATRY_AGAIN: str=_T("Non-authoritative host not found");break; case WSAVERNOTSUPPORTED: str=_T("WINSOCK.DLL version out of range");break; case WSAEDISCON: str=_T("Graceful shutdown in progress");break; case WSA_OPERATION_ABORTED: str=_T("Overlapped operation aborted");break; default: str.Format(_T("Unknown error %d (0x%08x)"),nErr,nErr); } #else // UNIX 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; default: str=strerror(errno); } #endif return str; } bool CeCosSocket::sendInteger(int n,LPCTSTR pszMsg,Duration dTimeout) { // This has to support cross-architectural endianness unsigned char c[sizeof(int)]; for(unsigned int i=0;i<sizeof(int);i++){ c[i]=(unsigned char)(n&0xff); n>>=8; } return send (c, sizeof(int),pszMsg,dTimeout); } bool CeCosSocket::recvInteger(int & n,LPCTSTR pszMsg,Duration dTimeout) { // This has to support cross-architectural endianness unsigned char c[sizeof(int)]; bool rc=recv (c, sizeof(int),pszMsg,dTimeout); n=0; if(rc){ for(int i=sizeof(int)-1;i>=0;--i){ n<<=8; n|=c[i]; } } return rc; } // Socket communications for strings are always non-UNICODE: bool CeCosSocket::recvString (String &str,LPCTSTR pszMsg,Duration dTimeout) { int nLength; bool rc=false; if(recvInteger(nLength,pszMsg,dTimeout)){ if(0==nLength){ rc=true; } else { Buffer b(1+nLength); char *c=(char *)b.Data(); if(c){ rc=recv(c,nLength,pszMsg,dTimeout); c[nLength]='\0'; str=String::CStrToUnicodeStr(c); } } } return rc; } // Socket communications for strings are always non-UNICODE: bool CeCosSocket::sendString (const String &str,LPCTSTR pszMsg,Duration dTimeout) { char *psz=str.GetCString(); int nLength=strlen(psz); bool rc=sendInteger(nLength,pszMsg,dTimeout) && (0==nLength || send(psz,nLength,pszMsg,dTimeout)); delete [] psz; return rc; } // Give indication of bytes available to be read (but don't read them) bool CeCosSocket::Peek (unsigned int &nAvail) { char buf[8192]; int n=::recv(m_nSock, buf, sizeof buf, MSG_PEEK); nAvail=0; bool rc=false; switch(n) { case -1: SaveError(); if(WOULDBLOCK==SocketError()){ rc=true; // nAvail stays==0 } else { ERROR(_T("Peek: err=%d %s\n"),SocketError(),(LPCTSTR)SocketErrString()); } break; case 0: m_nErr=ERR_READ_AFTER_CLOSE; break; default: rc=true; nAvail=n; } return rc; } // Connect tcp/ip port and serial port together. // Traffic is passed through pFunc, passed parameter pParam. // The pFunc function: // may reallocate pBuf (using malloc/realloc etc...) // must leave pBuf allocated on exit // should not close either serial or socket // should leave writing to its caller // should return false if it wishes to terminate the connection (after caller has written output) bool CeCosSocket::ConnectSocketToSerial (CeCosSocket &socket,CeCosSerial &serial,FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/,bool *pbStop/*=0*/) { serial.ClearError(); enum {BUFSIZE=8192}; void *pBuf=malloc(BUFSIZE); TRACE(_T("ConnectSocketToSerial: connected\n")); bool rc=true; try { /* { //hack unsigned int nWritten;//hack serial.Write(_T("+"),1,nWritten);//hack }//hack */ while(rc && (0==pbStop || !(*pbStop))){ unsigned int nRead=0; switch(SSRead (serial,socket,pBuf,BUFSIZE,nRead,pbStop)){ case SS_SERIAL_READ: VTRACE(_T("Serial:%d\n"),nRead); if(pSerialToSocketFilterFunc){ rc=pSerialToSocketFilterFunc(pBuf,nRead,serial,socket,pSerialParam); } if(nRead && !socket.send(pBuf,nRead)){ TRACE(_T("Failed to write to socket\n")); rc=false; } break; case SS_SOCKET_READ: unsigned int nWritten; VTRACE(_T("Socket:%d\n"),nRead); if(pSocketToSerialFilterFunc){ rc=pSocketToSerialFilterFunc(pBuf,nRead,serial,socket,pSocketParam); } { LPTSTR c=(LPTSTR )pBuf; int nToWrite=nRead; while(nToWrite>0){ if(!serial.Write(pBuf,nRead,nWritten)){ TRACE(_T("Failed to write to serial\n")); rc=false; break; } nToWrite-=nWritten; c+=nWritten; } } break; // Error conditions: case SS_SERIAL_ERROR: TRACE(_T("SSRead serial error - %s\n"),(LPCTSTR)serial.ErrString()); rc=false; break; case SS_SOCKET_ERROR: TRACE(_T("SSRead socket error - %s\n"),(LPCTSTR)socket.SocketErrString()); rc=false; break; case SS_STOPPED: TRACE(_T("SSRead stopped\n")); rc=false; break; } } } catch (...){ ERROR(_T("!!! ConnectSocketToSerial exception caught!!!\n")); free(pBuf); throw; } free(pBuf); return rc; } // Connect two tcp/ip ports together. // Traffic is passed through pFunc, passed parameter pParam. // The pFunc function: // may reallocate pBuf (using malloc/realloc etc...) // must leave pBuf allocated on exit // should not close either serial or socket // should leave writing to its caller // should return false if it wishes to terminate the connection (after caller has written output) bool CeCosSocket::ConnectSocketToSocket (CeCosSocket &o,FilterFunc *pSocketToSocketFilterFunc1,FilterFunc *pSocketToSocketFilterFunc2,void *pParam,bool *pbStop) { enum {BUFSIZE=8192}; void *pBuf=malloc(BUFSIZE); TRACE(_T("ConnectSocketToSocket: connected\n")); bool rc=true; try { while(rc && (0==pbStop || !(*pbStop))){ fd_set set; FD_ZERO(&set); FD_SET((unsigned)m_nSock, &set); FD_SET((unsigned)o.m_nSock, &set); struct timeval tv; tv.tv_sec = 1; tv.tv_usec = 0; switch(::select(m_nSock,&set,0,0,&tv)){ case -1: rc=false; break; case 1: case 2: { unsigned int nAvail=0; if(FD_ISSET((unsigned)m_nSock, &set) && Peek(nAvail) && recv(pBuf,nAvail)){ //rc=pSocketToSocketFilterFunc1(pBuf,nAvail,socket,this,o); o.send(pBuf,nAvail); } if(FD_ISSET((unsigned)o.m_nSock, &set) && o.Peek(nAvail) && o.recv(pBuf,nAvail)){ //rc=pSocketToSocketFilterFunc2(pBuf,nAvail,socket,o,this); send(pBuf,nAvail); } } case 0: break; } } } catch (...){ TRACE(_T("!!! ConnectSocketToSocket exception caught!!!\n")); rc=false; } free(pBuf); return rc; } bool CeCosSocket::ConnectSocketToSerial ( int nListenSock,LPCTSTR pszPort, int nBaud, FilterFunc *pSerialToSocketFilterFunc/*=0*/,void *pSerialParam/*=0*/,FilterFunc *pSocketToSerialFilterFunc/*=0*/,void *pSocketParam/*=0*/, bool *pbStop) { bool rc=false; try{ TRACE(_T("ConnectSocketToSerial : socket %d <--> %s\n"),nListenSock,pszPort); CeCosSerial serial; serial.SetBlockingReads(false); // Open serial device. if (!serial.Open(pszPort,nBaud)){ ERROR(_T("Couldn't open port %s\n"),pszPort); } else { // Flush the serial buffer. serial.Flush(); TRACE(_T("ConnectSocketToSerial: waiting for connection...\n")); CeCosSocket socket; if(!socket.Accept(nListenSock,pbStop)){ ERROR(_T("ConnectSocketToSerial - couldn't accept\n")); } else { rc=ConnectSocketToSerial (socket,serial,pSerialToSocketFilterFunc,pSerialParam,pSocketToSerialFilterFunc,pSocketParam,pbStop); } } TRACE(_T("ConnectSocketToSerial : done\n")); } catch(...){ TRACE(_T("ConnectSocketToSerial !!!exception handled!!!\n")); } return rc; } String CeCosSocket::ClientName(int nClient) { char ip[4]; memcpy(ip,&nClient,4); struct hostent *he=::gethostbyaddr((const char *)ip,4,AF_INET); String str; if(he){ str=String::CStrToUnicodeStr(he->h_name); } else { str.Format(_T("%u.%u.%u.%u"),ip[0],ip[1],ip[2],ip[3]); } return str; } String CeCosSocket::HostPort(LPCTSTR pszHost,int nPort) { String str; str.Format(_T("%s:%d"),pszHost,nPort); return str; } // Split the string into host:port parts. Result tells us whether it was successful. bool CeCosSocket::ParseHostPort (LPCTSTR pszHostPort, String &strHost, int &nPort) { int n=_stscanf(pszHostPort,_T("%[^:]:%d"),strHost.GetBuffer(_tcslen(pszHostPort)),&nPort); strHost.ReleaseBuffer(); return 2==n && nPort>0 && nPort<=0xffff; } // Is the string in the form host:port? bool CeCosSocket::IsLegalHostPort (LPCTSTR pszHostPort) { int nPort=0; String strHost; return ParseHostPort(pszHostPort,strHost,nPort); } // Translate a timeout that may be one of the special values DEFAULTTIMEOUT or NOTIMEOUT to a value in milliseconds. Duration CeCosSocket::TimeoutDuration(Duration dTimeout) { switch(dTimeout){ case DEFAULTTIMEOUT: dTimeout=m_nDefaultTimeout; break; case NOTIMEOUT: dTimeout=0x7fffffff; break; default: break; } return dTimeout; } String CeCosSocket::SocketErrString() { return SocketErrString(m_nErr); } bool CeCosSocket::SameHost(LPCTSTR host1, LPCTSTR host2) { return 0==_tcscmp(host1,host2) || (GetHostByName(host1)==GetHostByName(host2)); } bool CeCosSocket::Init() { #ifdef _WIN32 WSADATA wsaData; WORD wVersionRequested = MAKEWORD( 2, 0 ); WSAStartup( wVersionRequested, &wsaData ); #endif return true; } void CeCosSocket::Term() { #ifdef _WIN32 WSACleanup(); #endif } LPCTSTR CeCosSocket::MyHostName() { static String str; if(str.empty()){ char szMyname[256]; if(0==gethostname(szMyname,sizeof szMyname)){ str=String::CStrToUnicodeStr(szMyname); } } return str; } LPCTSTR CeCosSocket::MySimpleHostName() { static String str; if(str.empty()){ str=MyHostName(); // Remove all after a '.' LPCTSTR c=_tcschr(str,_TCHAR('.')); if(c){ str.resize(c-(LPCTSTR)str); } } return str; } const String CeCosSocket::GetHostByName(LPCTSTR pszHost) { typedef std::map<String,String> MapStringToString; static MapStringToString hostmap; MapStringToString::iterator it=hostmap.find(pszHost); if(hostmap.end()==it){ char *h=0; // avoid erroneous gcc warning message h=String(pszHost).GetCString(); char ip[16]; struct hostent* host_dat; if (0!=(host_dat=::gethostbyname(h))){ char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); if(c){ strcpy(ip,c); hostmap[pszHost]=String::CStrToUnicodeStr(ip); } } delete [] h; return String::CStrToUnicodeStr(ip); } else { return it->second; } }