📄 ecostestsocket.cpp
字号:
//=================================================================//// eCosTestSocket.cpp//// Socket test class////=================================================================//####COPYRIGHTBEGIN####// -------------------------------------------// The contents of this file are subject to the Cygnus eCos Public License// Version 1.0 (the "License"); you may not use this file except in// compliance with the License. You may obtain a copy of the License at// http://sourceware.cygnus.com/ecos// // Software distributed under the License is distributed on an "AS IS"// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the// License for the specific language governing rights and limitations under// the License.// // The Original Code is eCos - Embedded Cygnus Operating System, released// September 30, 1998.// // The Initial Developer of the Original Code is Cygnus. Portions created// by Cygnus are Copyright (C) 1998, 1999 Cygnus Solutions.// All Rights Reserved.// -------------------------------------------////####COPYRIGHTEND####//=================================================================//#####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 "stdafx.h"#include "eCosTestSocket.h"#include "eCosTestSerial.h"enum {ERR_TIMEOUT=20000, ERR_READ_AFTER_CLOSE=20001};int CeCosTestSocket::nDefaultSocketTimeout=10*1000; // milliseconds// Non-blocking read on one or other of the data sources:// Result: 0 - error occurred// 1 - data read from socket// 2 - data read from serialint SSRead (CeCosTestSerial &serial,CeCosTestSocket &socket,void *pBuf,unsigned int nSize,unsigned int &nRead){ int rc=0; bool bBlocking=serial.GetBlockingReads(); bool bBlockingModified=false; for(;;){ CeCosTestUtils::Time ft0=CeCosTestUtils::Time::Now(); 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; } } CeCosTestUtils::Sleep(1); } if(bBlockingModified){ serial.SetBlockingReads(true); } return rc;}// ctors and dtorsCeCosTestSocket::CeCosTestSocket (): m_nSock(-1), m_nClient(0){}CeCosTestSocket::CeCosTestSocket (int sock /*result of previous call of Listen*/, bool *pbStop): m_nSock(-1), m_nClient(0){ Accept(sock,pbStop);}CeCosTestSocket::CeCosTestSocket (CeCosTestUtils::String strHost,int port,Duration dTimeout): m_nSock(-1), m_nClient(0){ Connect(strHost,port,dTimeout);}bool CeCosTestSocket::Accept(int sock /*result of previous call of Listen*/, bool *pbStop){ m_nSock=-1; while(-1==m_nSock && (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()){ CeCosTestUtils::Sleep(100); continue; } } unsigned char ip[4]; memcpy(ip,cli_addr.sa_data+2,4); memcpy(&m_nClient,ip,4); struct hostent *he=::gethostbyaddr((char *)ip,4,AF_INET); SaveError(); if(he){ TRACE("Connection accepted from %s - socket %d\n",he->h_name,m_nSock); } else { TRACE("Connection accepted from %u.%u.%u.%u\n - socket %d",ip[0],ip[1],ip[2],ip[3],m_nSock); } SetSocketOptions(); } m_nOpenrc=0; return -1!=m_nSock;}int CeCosTestSocket::Listen(int nTcpPort){ // Create socket int sock=::socket(AF_INET, SOCK_STREAM, 0); if (sock == -1) { TRACE("Couldn't create socket\n"); } else { TRACE("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("Couldn't bind socket on port %d\n",nTcpPort); CloseSocket(sock); } else if (-1==::listen(sock, 5)){ CloseSocket(sock); TRACE("socket error on listen - port %d\n",nTcpPort); } else { #ifdef _WIN32 int nTrue=1; bool rc=(0==::ioctlsocket(sock, FIONBIO, (unsigned long *)&nTrue)); #else int flags=::fcntl(sock,F_GETFL); flags|=O_NONBLOCK; bool rc=(0==::fcntl (sock, F_SETFL, flags)); #endif if(!rc){ TRACE("Failed to set socket options on socket %d\n",sock); } } } return sock;}bool CeCosTestSocket::Connect(CeCosTestUtils::String strHost,int port,Duration dTimeout){ struct sockaddr_in serv_addr; struct hostent* host_dat; char ip[16]; // for nnn.nnn.nnn.nnn m_nOpenrc=0; VTRACE("Connect: %s:%d timeout=%d\n",(const char *)strHost,port,dTimeout); // Get the target host address CeCosTestUtils::String strErr; if (0==(host_dat=::gethostbyname((const char *)strHost))) { SaveError(); TRACE("Could not get IP address for host %s - %s\n",(const char *)strHost,(const char *)SocketErrString()); m_nOpenrc=SocketError(); } else { const char *c=(char*)inet_ntoa( *( (struct in_addr *)host_dat->h_addr_list[0] ) ); if(0==c){ SaveError(); TRACE("Could inet_ntoa %s - %s\n",(const char *)strHost,(const char *)SocketErrString()); m_nOpenrc=SocketError(); } 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("Could not create socket [%s:%d]\n",(const char *)strHost,port); m_nOpenrc=SocketError(); } else { #ifdef _WIN32 SetSocketOptions(); #endif TRACE("Created socket %d connected to %s:%d\n",m_nSock,(const char *)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("Connect() : connecting to server\n"); int cc=::connect(m_nSock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); SaveError(); CeCosTestUtils::String strMsg; if(-1==cc){ m_nOpenrc=SocketError(); if( #ifdef _WIN32 WOULDBLOCK==m_nOpenrc #else EINPROGRESS==m_nOpenrc #endif ){ // Allow 5 seconds for connect to complete fd_set set; FD_ZERO(&set); FD_SET((unsigned)m_nSock, &set); struct timeval tv; tv.tv_sec = dTimeout/1000; tv.tv_usec = 0; switch(::select(m_nSock, NULL, &set , NULL, &tv)){ case 0: SaveError(); strMsg.Format("attempt timed out after %d seconds",dTimeout/1000); m_nOpenrc=-1; cc=-1; break; case -1: SaveError(); m_nOpenrc=SocketError(); strMsg=SocketErrString(); break; default: m_nOpenrc=0; cc=0; } } else { strMsg=SocketErrString(); } } if(-1==cc){ TRACE("Could not connect to %s:%d - %s\n",(const char *)strHost,port,(const char *)strMsg); CloseSocket(m_nSock); } else { #ifndef _WIN32 SetSocketOptions(); #endif } } } } return -1!=m_nSock;}bool CeCosTestSocket::sendrecv(bool bSend,const void *pData,unsigned int nLength, const char *pszMsg,CeCosTestSocket::Duration dTimeout,CeCosTestSocket::StopFunc pFnStop,void *pParam){ const char *pszSR=(bSend?"sending":"receiving");//TRACE("%s %s [%d bytes]\n",pszSR,pszMsg,nLength); char *c=(char *)pData; CeCosTestUtils::Time ft0=CeCosTestUtils::Time::Now(); int nTodo=nLength; enum { RETRYDELAY=100 };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -