📄 ecostestsocket.cpp
字号:
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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::ConnectSocketToSerial (CeCosTestSocket &socket,CeCosTestSerial &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 2: 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 1: 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; case 0: TRACE(_T("SSRead returned error indication\n")); rc=false; break; // Error } } } catch (...){ TRACE(_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 CeCosTestSocket::ConnectSocketToSocket (CeCosTestSocket &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 CeCosTestSocket::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); CeCosTestSerial 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")); CeCosTestSocket 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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::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 CeCosTestSocket::TimeoutDuration(Duration dTimeout){ switch(dTimeout){ case DEFAULTTIMEOUT: dTimeout=m_nDefaultTimeout; break; case NOTIMEOUT: dTimeout=0x7fffffff; break; default: break; } return dTimeout;}bool CeCosTestSocket::IsSocketError(int n){ #ifdef _WIN32 return n>=WSABASEERR && n<30000; // include our own (e.g. ERR_READ_AFTER_CLOSE) #else // UNIX return true; #endif}String CeCosTestSocket::SocketErrString() { return SocketErrString(m_nErr); }bool CeCosTestSocket::SameHost(LPCTSTR host1, LPCTSTR host2){ char *h1=String(host1).GetCString(); char *h2=String(host2).GetCString(); char ip1[16],ip2[16]; struct hostent* host_dat; bool rc=(0==_tcscmp(host1,host2)); if (0!=(host_dat=::gethostbyname(h1))){ char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); if(c){ strcpy(ip1,c); if (0!=(host_dat=::gethostbyname(h2))){ char *c=inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); if(c){ strcpy(ip2,c); } } rc=(0==strcmp(ip1,ip2)); } } delete [] h1; delete [] h2; return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -