网络通信

来源:互联网 发布:movidius 计算棒 知乎 编辑:程序博客网 时间:2024/05/17 01:50
/**  * @file Socket.h * @brief 封装对套接字的操作 */#ifndef __SOCKET_H__#define __SOCKET_H__#include "NetComm.h"namespace lspublic{    namespace library    {        namespace net        {            /**              * @brief 套接字类             *             */            class CSocket : public intf::IErrMsg            {                public:                    CSocket();                    ~CSocket();                public://静态函数                    /**                      * @brief 初始化套接字                     * win32平台上需要对套接字环境进行初始化                     *                     */                    static void InitializeSock();                    /**                      * @brief 判断一组套接字是否有数据到达                     *                      * @param socks[]  套接字数组                     * @param nSocksCount 套接字数量                     * @param waitMilliseconds 等待时间                     *                      * @return bool                     * @retval true 有数据等待接受                     * @retval false 没有数据等待接受                     */                    static bool Select(CSocket* socks[], int nSocksCount, long waitMilliseconds = -1);                    /**                      * @brief 获取主机地址(如果有多个,那么获取第一个)                     *                      * @param addr 主机地址                     *                      * @return int                     * @retval 0 成功                     * @retval -1 失败                     * @warning 可能存在越界访问                     */                    static int GetHostAddr(char* addr,uint32_t nLen);                    /**                      * @brief 获取主机地址列表                     *                      * @param addr 地址数组指针                     * @param count 地址个数                     *                      * @return                      */                    static int GetHostAddr(struct in_addr*& addr, int& count);                public:                    /**                      * @brief 创建套接字                     *                      * @param nSockPort 端口                     * @param pszSockAddr 地址                     * @param nType 类型                     * @param nReuseFlag 地址重用标志:0 不重用;1 重用                     *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool Create(int nSockPort = 0, const char* pszSockAddr = NULL, int nType = SOCK_STREAM, int nReuseFlag = 0);                    /**                      * @brief 绑定套接字                     *                     * 绑定到指定的端口,地址                     *                      * @param nSockPort 端口号                     * @param pszSockAddr 地址                     *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool Bind(int nSockPort, const char* pszSockAddr = NULL);                    /**                      * @brief 建立监听                     *                      * @param nConnectionBacklog                      *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool Listen(int nConnectionBacklog = 5);                    /**                      * @brief 建立连接                     *                     * @param nHostPort 端口号                     * @param pszHostAddr 地址                     * @param tryTimes 重试次数                     *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool Connect(int nHostPort, const char* pszHostAddr = NULL, int tryTimes = 1);                    /**                      * @brief  重新连接                     *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool Reconnect();                    /**                      * @brief 接收一个套接字的链接请求                     *                      * @param rConnectedSock                     * @param pAddr 对端地址 (尚未实现)                     * @param pAddrLen 对端地址长度(尚未实现)                     *                      * @return bool                       */                    bool Accept(CSocket* rConnectedSock, SOCKADDR* pAddr = NULL, int* pAddrLen = NULL);                    /**                      * @brief 从套接字读取数据                     *                      * @param lpBuf   缓冲块指针                     * @param nBufLen 缓冲块大小                     * @param nFlags 标志                     *                      * @return int                     * @retval >=0 读取到的字节数                     * @retval <0 读取失败                     */                    int Recv(void* lpBuf, int nBufLen, int nFlags = MSG_EXPECTED);                    /**                      * @brief 向套接字发送数据                     *                      * @param lpBuf 数据块指针                     * @param nBufLen 数据长度                     * @param nFlags 标志                     *                      * @return int                     * @retval >0 发送出去的字节数                     * @retval <0 发送失败                     */                    int Send(const void* lpBuf, int nBufLen, int nFlags = 0);                                        /**                     * @brief socket shutdown                     *                     * @return bool                     */                    bool ShutDown();                                        /**                      * @brief 关闭套接字                     *                      * @return                      */                    int Close();                    /**                      * @brief 以Linger模式关闭套接字                     *                      * @param nSeconds Linger等待时长                     *                      * @return int                     * @retval 0 成功                     * @retval 非0 失败                     *                     */                    int Close(uint32_t nSeconds);                    /**                      * @brief 设置阻塞模式                     *                      * @param blocking true 阻塞模式; false 一步模式                     *                      * @return bool                     * @retval true 成功                     * @retval false 失败                     */                    bool SetBlockMode(bool blocking = true);                    /**                      * @brief 设置套接字句柄                     * 将一个已经链接好的SocketId设置到类中                     * @param nSocketId 套接字句柄                     * @warning 必须是已经建立连接的句柄                     */                    void SetSocket(int nSocketId)                    {                        m_hHandle = nSocketId;                        m_bConnected = true;                    };                    /**                      * @brief 获取套接字句柄                     *                      * @return SOCKET                     * @retval 句柄                     */                    SOCKET GetHandle() { return m_hHandle; }                    /**                      * @brief 判断套接字是否打开                     *                      * @return bool                     * @retval true  链接打开                     * @retval false 链接未打开                     */                    bool IsOpen() {return m_hHandle != 0; }                    /**                      * @brief 获取套接字地址                     *                      *                     * @return SOCKADDR                     *                     */                    const SOCKADDR_IN& GetAddr()                     {                        return m_sin;                    }                    /**                      * @brief 判断当前是否处于写阻塞                     *                      * @return  bool                     * @retval true 写阻塞中                     * @retval false 非阻塞                     */                    bool IsBlocking();                    /**                      * @brief 判断是否有数据等待接收                     *                      * @param waitMilliseconds 等待时长(单位微秒)                     *                      * @return bool                     * @retval true 有数据到达                     * @retval false 没有数据到达                     */                    bool DataArrival(long waitMilliseconds = -1);                    /**                      * @brief 是否有数据等待接受                     *                      * @return bool                     * @retval true 有数据等待接受                     * @retfal false 没有数据等待接受                     *                      */                    bool IsSelected() { return m_bSelected; }                    /**                      * @brief 判断套接字是否关闭                     *                      * @return bool                     * @retval true 关闭的                     * @retval false 打开的                     */                    bool IsClosed() { return !m_bConnected; }                    /**                      * @brief 判断套接字是否处于链接状态                     *                      * @return bool                     * @retval true 是                     * @retval false 否                     */                    bool IsConnected() { return m_bConnected; }                    /**                      * @brief socket连接是否超时                     *                     * @param nOutTime 超时时长                     * @param nFlag  0:不更新开始时间,  >0 更新socket开始时间。                     *                      * @return int                     * @retval 0 未超时                     * @retval 1 超时                     */                    int IsTimeOut(int nOutTime, int nFlag);                    /**                      * @brief 获取Socket地址                     *                      * @return IP地址                     */                    char* GetHostIP();                    /**                      * @brief 获取最新的错误信息                     *                      * @return 错误信息                     */                    const char* GetLastErrMsg() { return m_szLastErr; }                private:                    void initaddr(int nSockPort, const char* pszSockAddr = NULL);                    void SetErrMsg(const char* fmt,...);                private:                    SOCKET m_hHandle;                    SOCKADDR_IN m_sin;                    bool m_bConnected;                    bool m_bSelected;                    char m_szLastErr[1024];                    time_t m_tBeginTime; //开始时间#ifdef WIN32                public:                    static bool m_bInitialized;#endif            };        }    }}#endif //__SOCKET_H__


 

///////////////////////////////////////////////////////////////////////// socket.cpp:  socket class realization///////////////////////////////////////////////////////////////////////#include "Socket.h"#include <netinet/tcp.h>#ifdef WIN32bool CSocket::m_bInitialized = false;#endifusing namespace lspublic::library::net;void CSocket::InitializeSock(){#ifdef WIN32if (!m_bInitialized) {WORD ver; WSADATA wsa;ver = MAKEWORD( 2, 2 );int ret = WSAStartup(ver, &wsa);}#endif}//Initialization.CSocket::CSocket(){m_bConnected = false;m_bSelected  = false;m_hHandle = 0;m_szLastErr[0] = '\0';memset(&m_sin,0x0,sizeof(SOCKADDR_IN));time(&m_tBeginTime);#ifdef WIN32if (!m_bInitialized){int ret;WORD ver; WSADATA wsa;ver = MAKEWORD( 2, 2 );ret = WSAStartup(ver, &wsa);if (ret != 0)        {SetErrMsg("Initializing socket failed!");        }}#endif}//Deconstruction.CSocket::~CSocket(){//Close socket before destroying itif (m_hHandle > 0) Close();}int CSocket::IsTimeOut(int nOutTime, int nFlag){int nStat = 0;time_t nowtim;time(&nowtim);if((nowtim - m_tBeginTime >= nOutTime) && nFlag == 0) nStat = 1;if(nFlag > 0)m_tBeginTime = nowtim;return nStat;}void CSocket::initaddr(int nSockPort, const char* pszSockAddr){memset(&m_sin,0x0,sizeof(struct sockaddr_in));m_sin.sin_family = AF_INET;if (nSockPort != 0)m_sin.sin_port = htons((unsigned short)nSockPort);if (pszSockAddr != NULL){if(pszSockAddr[0]>='0' && pszSockAddr[0]<='9'){#ifdef WIN32m_sin.sin_addr.s_addr = inet_addr(pszSockAddr);#elseif ((inet_aton(pszSockAddr,&(m_sin.sin_addr))) == 0)            {                return;            }#endif}else{//如果是使用名字的struct hostent *hp;hp = gethostbyname(pszSockAddr);if (hp == 0)            {SetErrMsg("%s: unknown host!", pszSockAddr);return;}memcpy((char*)&m_sin.sin_addr, (char*)hp->h_addr, hp->h_length);}}}bool CSocket::Create(int nSockPort, const char* pszSockAddr, int nType, int nReuseFlag){initaddr(nSockPort, pszSockAddr);m_hHandle = socket(AF_INET, nType, 0);if (!m_hHandle){SetErrMsg("Failed to create a socket. syserr:%d-%s", errno, strerror(errno));return false;}int on=nReuseFlag;    int status = 0; //xsj modify 20090716status = setsockopt(m_hHandle,SOL_SOCKET,SO_REUSEADDR,(const char *) &on, sizeof(on));if (-1 == status){SetErrMsg( "%s:%d 警告:设置重用属性失败!(Port=%s:%d)\n", __FILE__, __LINE__, pszSockAddr, nSockPort);Close();return false;}on = 1;status = setsockopt(m_hHandle,IPPROTO_TCP, TCP_NODELAY, (const char *) &on, sizeof(on));if (-1 == status){SetErrMsg( "%s:%d 警告:设置TCP_NODELAYACK失败!(Port=%s:%d)\n", __FILE__, __LINE__, pszSockAddr, nSockPort);Close();return false;}return true;}bool CSocket::ShutDown(){    if (m_hHandle > 0)    {        int nRet = shutdown(m_hHandle, 2);        if (nRet != 0)        {            return false;        }    }    return true;}int CSocket::Close(){    int nRet = 0;    if (m_hHandle > 0)    { nRet = closesocket(m_hHandle);    }    if( 0 != nRet)    {        SetErrMsg("closesocket failed:errno=%d,errmsg=%s",errno,strerror(errno));        return nRet;    }    m_hHandle = 0;    m_bConnected = false;    return 0;}int CSocket::Close(uint32_t nSeconds){    struct linger Linger;    Linger.l_onoff = 1;    Linger.l_linger = nSeconds;    setsockopt(m_hHandle, SOL_SOCKET, SO_LINGER, (char *)&Linger,sizeof(Linger));    return Close();}bool CSocket::Bind(int nSockPort, const char* pszSockAddr){initaddr(nSockPort, pszSockAddr);int ret = bind(m_hHandle, (SOCKADDR *)(void *)&m_sin,(socklen_t)sizeof(SOCKADDR_IN));if (ret != 0){SetErrMsg( "Cann't bind on %s:%d. syserr:%d-%s", pszSockAddr, nSockPort, errno, strerror(errno));return false;}return true;}//Listen on certaion address and portbool CSocket::Listen(int nConnectionBacklog){if(listen(m_hHandle, nConnectionBacklog) == -1){SetErrMsg( "Listening on %d failed. syserr:%d-%s", m_hHandle, errno, strerror(errno));return false;}return true;}//Connect to a listenning socketbool CSocket::Connect(int nHostPort, const char* pszHostAddr, int tryTimes){initaddr(nHostPort, pszHostAddr);if(connect(m_hHandle, (SOCKADDR *)(void *)&m_sin, (socklen_t)(sizeof(SOCKADDR_IN))) == -1){SetErrMsg( "Connecting to %s:%d failed. syserr:%d-%s", pszHostAddr, nHostPort, errno, strerror(errno));return false;}m_bConnected = true;return true;}//Accept a connectionbool CSocket::Accept(CSocket* rConnectedSock, SOCKADDR* pAddr, int* pAddrLen){//In HP #ifdef _XOPEN_SOURCE_EXTENDED    socklen_t uLen = sizeof(SOCKADDR_IN);#else    int uLen = sizeof(SOCKADDR_IN);#endifrConnectedSock->m_hHandle = accept(m_hHandle,(SOCKADDR *)(void *)&(rConnectedSock->m_sin), &uLen);if (rConnectedSock->m_hHandle < 0)//--zfl modify 20090825 BSS-34702{SetErrMsg( "Failed to accept a connection on %d. syserr:%d-%s", m_hHandle, errno, strerror(errno));return false;}rConnectedSock->m_bConnected = true;return true;}//Recv dataint CSocket::Recv(void* lpBuf, int nBufLen, int nFlags){int len = 1, tot = 0;if (nFlags & MSG_EXPECTED){while (tot < nBufLen && len > 0){#ifdef WIN32len = recv(m_hHandle, ((char *)lpBuf) + tot, nBufLen - tot, 0);#elselen = recv(m_hHandle, (void *)(((char *)lpBuf) + tot), nBufLen - tot, 0);#endifif (len > 0) tot += len;}//Win32测试结果,当对方非正常关闭,返回值可能为-1或0if (len <= 0 ){SetErrMsg("CSocket:recievied with len < 0. syserr:%d-%s", errno, strerror(errno));Close();return len;}if (tot > 0 && tot < nBufLen){SetErrMsg( "Expected %d bytes, while received %d bytes. syserr:%d-%s", nBufLen, tot, errno, strerror(errno));return -1;}return tot;}else{#ifdef WIN32len = recv(m_hHandle, (char *)lpBuf, nBufLen, 0);#elselen = recv(m_hHandle, lpBuf, nBufLen, 0);#endif if (len == -1)        {SetErrMsg( "Recving data failed. syserr:%d-%s", errno, strerror(errno));        }if (len == 0)        {            //收取不到数据        }if(len <= 0)        {SetErrMsg("Recving data failed. syserr:%d-%s", errno, strerror(errno));        } return len;}}//Send dataint CSocket::Send(const void* lpBuf, int nBufLen, int nFlags){int len;#ifdef WIN32len = send(m_hHandle, (const char*)lpBuf, nBufLen, nFlags);#elselen = send(m_hHandle, lpBuf, nBufLen, nFlags);#endif//Win32测试结果,当对方非正常关闭,返回值可能为-1或0//if (len == -1)if (len <=0 ){SetErrMsg( "Sending data failed. syserr:%d-%s", errno, strerror(errno));return -1;}return len;}bool CSocket::IsBlocking(){struct timeval timeout = {0, 0};fd_set fdsck;memset(&fdsck, '\0', sizeof(fdsck));FD_SET((unsigned long)m_hHandle, &fdsck);select(m_hHandle+1, NULL, &fdsck, NULL, &timeout);if(!FD_ISSET((unsigned long)m_hHandle, &fdsck))return false;return true;}//Sets blocking modebool CSocket::SetBlockMode(bool blocking){#ifdef WIN32return true;#elseint iBlockFlag;//Blocking or notif((iBlockFlag = fcntl(m_hHandle, F_GETFL)) == -1){SetErrMsg( "Failed to test the socket mode. syserr:%d-%s", errno, strerror(errno));return false;}if(blocking){//SynchronizeiBlockFlag = iBlockFlag&(~O_NDELAY);}else{//AsynchronizeiBlockFlag = iBlockFlag | O_NDELAY;}if(fcntl(m_hHandle, F_SETFL, iBlockFlag) == -1){SetErrMsg( "Failed to set the socket mode. syserr:%d-%s", errno, strerror(errno));return false;}return true;#endif}//Return whether there is data in the incomming bufferbool CSocket::DataArrival(long waitMilliseconds){if (m_hHandle <= 0){        SetErrMsg("Invalid Socket Handle : %d",m_hHandle);return false;}fd_set fdsck;FD_ZERO(&fdsck);FD_SET((unsigned long)m_hHandle, &fdsck);if(waitMilliseconds >= 0){struct timeval timeout;        timeout.tv_sec =waitMilliseconds / 1000;        timeout.tv_usec =(waitMilliseconds % 1000) * 1000;select(m_hHandle+1, &fdsck, NULL, NULL, &timeout);}else{select(m_hHandle+1, &fdsck, NULL, NULL, NULL);}if(FD_ISSET((unsigned long)m_hHandle, &fdsck))return true;elsereturn false;}bool CSocket::Select(CSocket* socks[], int nSocksCount, long waitMilliseconds){fd_set fdsck;memset(&fdsck, '\0', sizeof(fdsck));int i;unsigned long maxId = 0;CSocket* s;for (i = 0; i < nSocksCount; i++){s = socks[i];if (s != NULL){s->m_bSelected = false;if (!s->IsClosed() && s->m_hHandle != 0){maxId = maxId > s->m_hHandle ? maxId : s->m_hHandle;FD_SET((unsigned long)s->m_hHandle, &fdsck);}}}//No socket is to be selectedif (maxId == 0) return false;if(waitMilliseconds >= 0){struct timeval timeout = { \waitMilliseconds / 1000, (waitMilliseconds % 1000) * 1000};select(maxId+1, &fdsck, NULL, NULL, &timeout);}else{select(maxId+1, &fdsck, NULL, NULL, NULL);}bool hasSelected = false;for (i = 0; i < nSocksCount; i++){s = socks[i];if (s != NULL && !s->IsClosed()){if(FD_ISSET((unsigned long)s->m_hHandle, &fdsck)){s->m_bSelected = true;hasSelected    = true;}}}return hasSelected;}char* CSocket::GetHostIP(){return inet_ntoa(m_sin.sin_addr);}int CSocket::GetHostAddr(char* addr,uint32_t nLen){char host[256] = "";InitializeSock();if (gethostname(host, 256) != 0)    {return -1;    }struct hostent * ht = gethostbyname(host);if (ht == NULL)    {return -1;    }// Return the first addrstruct in_addr in;memcpy(&in.s_addr, ht->h_addr_list[0], sizeof(in.s_addr));snprintf(addr,nLen,"%s",inet_ntoa(in));return 0;}int CSocket::GetHostAddr(struct in_addr*& addr, int& count){// Initialize socket (needed on windows)InitializeSock();char host[256] = "";count = 0;if (gethostname(host, 256) != 0)    {return -1;    }struct hostent * ht = gethostbyname(host);if (ht == NULL)    {return -1;    }if (ht->h_length == 0) return 0;char **p = ht->h_addr_list;for (; *p != 0; p++)count++;addr = new struct in_addr[count];count = 0;for (p = ht->h_addr_list; *p != 0; p++) {memcpy(&addr[count].s_addr, *p, sizeof(addr[count].s_addr));count++;}return 0;}void CSocket::SetErrMsg(const char* fmt,...){    va_list ap;    va_start(ap, fmt);    vsnprintf(m_szLastErr,sizeof(m_szLastErr),fmt, ap);    va_end(ap);}


 

 

#ifndef _NET_COMM_H_#define _NET_COMM_H_//引用系统文件#ifdef WIN32#include <winsock.h>#include "errno.h"#else // Unix socket header file #include <fcntl.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/errno.h>    #include <stdarg.h>#ifndef HPUX#include  <sys/select.h>#endif#endif//引用公共库文件#include "basic/Std.h"#include "basic/Macro.h"#include "basic/BasicTypes.h"#include "basic/DomainType.h"#include "intf/IErrMsg.h"//宏定义&类型定义#ifdef WIN32    #ifndef TYPEDEF_SOCKLEN    #define TYPEDEF_SOCKLEN                    typedef int socklen_t;    #endif    #define SLEEP(n)                                       Sleep(n*100)#else typedef struct sockaddr SOCKADDR;typedef struct sockaddr_in SOCKADDR_IN;#ifndef TYPEDEF_SOCKET#define TYPEDEF_SOCKET            typedef int SOCKET;#endif#define SOCKET_ERROR   (-1)#define INVALID_SOCKET (SOCKET)(~0)#define closesocket close    #define SLEEP(n)                                       sleep(n)    /*#ifndef INVALID_SOCKET#define INVALID_SOCKET                                 (int32_t)(~0) #endif    */#endif #define SOCKADDR_LEN sizeof(struct sockaddr)//SOCKLEN_T定义#define SOCKLEN_T socklen_t#ifdef HPUX#undef SOCKLEN_T#define SOCKLEN_T int#endif#ifdef WIN32#undef SOCKLEN_T#define SOCKLEN_T int#endif#ifdef _SCO_#undef SOCKLEN_T#define SOCKLEN_T int#endif#ifndef set_4bytes#define set_4bytes(_b,_v) {(_b)[0]=((_v)&0xff000000)>>24;(_b)[1]=((_v)&0x00ff0000)>>16;(_b)[2]=((_v)&0x0000ff00)>>8;(_b)[3]=((_v)&0x000000ff);}#endif#ifndef get_4bytes#define get_4bytes(_b) ((((unsigned int)((unsigned char *)_b)[0])<<24)|(((unsigned int)((unsigned char *)_b)[1])<<16)|(((unsigned int)((unsigned char *)_b)[2])<<8)|(((unsigned int)((unsigned char *)_b)[3])))#endif#ifndef O_NDELAY#define O_NDELAY 0000004#endiftypedef unsigned char  u_char;typedef unsigned short u_short;typedef unsigned int   u_int;typedef unsigned long  u_long;#ifdef NET_DEBUG#define DEBUG_LOG(arg...) do \{ \    fprintf(stdout,"[%s:%d:%d]",__FILE__,__LINE__,getpid()); \    fprintf(stdout,"\t"); \    fprintf(stdout,arg); \    fprintf(stdout,"\n"); \}while(0)#else#define DEBUG_LOG(arg...) #endifnamespace lspublic{    namespace library    {        namespace net        {            /**              * @brief Telnet常量定义             */            enum _TELNET_CONST_            {                IBAS_TELNET_NUM_CODEC = 6                    ,NUM_TERMINALS = 2                    ,IBAS_TELNET_NUM_TOPT_FUNC = 4                    ,IBAS_TELNET_NUL = 0                    ,IBAS_TELNET_BEL = 7                    ,IBAS_TELNET_BS = 8                    ,IBAS_TELNET_HT = 9                    ,IBAS_TELNET_LF = 10                    ,IBAS_TELNET_VT = 11                    ,IBAS_TELNET_FF = 12                    ,IBAS_TELNET_CR = 13                    ,IBAS_TELNET_SE = 240                    ,IBAS_TELNET_NOP = 241                    ,IBAS_TELNET_DM = 242                    ,IBAS_TELNET_BRK = 243                    ,IBAS_TELNET_IP = 244                    ,IBAS_TELNET_AO = 245                    ,IBAS_TELNET_AYT = 246                    ,IBAS_TELNET_EC = 247                    ,IBAS_TELNET_EL = 248                    ,IBAS_TELNET_GA = 249                    ,IBAS_TELNET_SB = 250                    ,IBAS_TELNET_WILL = 251                    ,IBAS_TELNET_WONT = 252                    ,IBAS_TELNET_DO = 253                    ,IBAS_TELNET_DONT = 254                    ,IBAS_TELNET_IAC = 255            };            /**              * @brief Telnet VERB 枚举             */            typedef enum _IBAS_TELNET_VERB            {                VERB_SB = 250,                VERB_WILL = 251,                VERB_WONT = 252,                VERB_DO = 253,                 VERB_DONT = 254            }ETelnetVerb;            /**              * @brief Telnet 状态枚举             */            typedef enum _IBAS_TELNET_STATE            {                STATE_DATA,             //we expect a data byte                STATE_CODE,             //we expect a code                STATE_OPTION            //we expect an option            }ETelnetState;            /**              * @brief Telnet选项             */            typedef enum _IBAS_TELNET_OPTION            {                TOPT_BIN = 0,   // Binary Transmission                TOPT_ECHO = 1,  // Echo                TOPT_RECN = 2,  // Reconnection                TOPT_SUPP = 3,  // Suppress Go Ahead                TOPT_APRX = 4,  // Approx Message Size Negotiation                TOPT_STAT = 5,  // Status                TOPT_TIM = 6,   // Timing Mark                TOPT_REM = 7,   // Remote Controlled Trans and Echo                TOPT_OLW = 8,   // Output Line Width                TOPT_OPS = 9,   // Output Page Size                TOPT_OCRD = 10, // Output Carriage-Return Disposition                TOPT_OHT = 11,  // Output Horizontal Tabstops                TOPT_OHTD = 12, // Output Horizontal Tab Disposition                TOPT_OFD = 13,  // Output Formfeed Disposition                TOPT_OVT = 14,  // Output Vertical Tabstops                TOPT_OVTD = 15, // Output Vertical Tab Disposition                TOPT_OLD = 16,  // Output Linefeed Disposition                TOPT_EXT = 17,  // Extended ASCII                TOPT_LOGO = 18, // Logout                TOPT_BYTE = 19, // Byte Macro                TOPT_DATA = 20, // Data Entry Terminal                TOPT_SUP = 21,  // SUPDUP                TOPT_SUPO = 22, // SUPDUP Output                TOPT_SNDL = 23, // Send Location                TOPT_TERM = 24, // Terminal Type                TOPT_EOR = 25,  // End of Record                TOPT_TACACS = 26, // TACACS User Identification                TOPT_OM = 27,   // Output Marking                TOPT_TLN = 28,  // Terminal Location Number                TOPT_3270 = 29, // Telnet 3270 Regime                TOPT_X3 = 30,  // X.3 PAD                TOPT_NAWS = 31, // Negotiate About Window Size                TOPT_TS = 32,   // Terminal Speed                TOPT_RFC = 33,  // Remote Flow Control                TOPT_LINE = 34, // Linemode                TOPT_XDL = 35,  // X Display Location                TOPT_ENVIR = 36,// Telnet Environment Option                TOPT_AUTH = 37, // Telnet Authentication Option                TOPT_NENVIR = 39,// Telnet Environment Option                TOPT_EXTOP = 255, // Extended-Options-List                TOPT_ERROR = 256  // Magic number            }ETelnetOpt;            /**              * @brief Telnet ANSI 状态             */            typedef enum _IBAS_TELNET_ANSI_STATE            {                AS_NORMAL,                AS_ESC,                AS_ESC1            }ETelnetAnsiState;            /**              * @brief Telnet 终端类型             */            typedef enum _IBAS_TELNET_TERM_TYPE            {                SB_TERM_IS = 0,                SB_TERM_SEND = 1            }ETelnetTermType;            /**              * @brief 文件传输协议类型             */            typedef enum _PROTOCOL_TYPE            {                FTP_PROTOCAL =  0                ,CTP_PROTOCAL = 1            }EProtocolType;            /**              * @brief 强制标志             */            typedef enum _FORCE_FLAG_            {                FORCE_FLAG_NORMAL=0 //非强制                    ,FORCE_FLAG_FORCE=1 //强制            }EForceType;#define MSG_EXPECTED 0x8#define FTP_DATABUFFER 8192  /*8K*/#define FTP_TIMEOUT    30            /**              * @brief Ftp verbose             */            typedef enum{                    FTP_DIR          = 1                    ,FTP_DIR_VERBOSE  = 2                    ,FTP_FILE_READ    = 3                    ,FTP_FILE_WRITE   = 4            }EFtpVerb;            // Ftp direction            typedef enum            {                     FTP_CONTROL= 0                    ,FTP_READ   = 1                    ,FTP_WRITE  = 2            }EFtpDirection;            /**              * @brief FtpAccessMode             */            typedef enum            {                FTP_ASCII   =   'A'               ,FTP_BINARY  =   'I'            }EFtpAccessMode;            /**              * @brief connection modes              */           typedef enum           {               FTP_PASSIVE      = 1              ,FTP_PORT         = 2            }EFtpConnMode;           /**             * @brief connection option names            */            typedef enum            {                    FTP_CONNMODE    = 1                    ,FTP_CALLBACK     = 2                    ,FTP_IDLETIME     = 3                    ,FTP_CBARG        = 4                    ,FTP_CBBYTES      = 5            }EConnOptNames;#define MAX_DIR_LEVEL 20            /**             * Common length macroes.             */#ifndef FNAME_LEN#define FNAME_LEN     256#endif#ifndef CFG_STRLEN#define CFG_STRLEN    128#endif#define ERR_MAXLEN    512#define CMD_MAXLEN    256#define _FTP_CONNECT_HOST_LENGTH_256+1 //ftp连接的IP地址长度#define _FTP_CONNECT_USER_NAME_LENGTH_256+1 //ftp连接的用户名长度#define _FTP_CONNECT_PASSWORD_LENGTH_256+1 //ftp连接的密码长度/** * FTP/CTP Error Define */#define SUCCESS        0#define FAILURE        1  //general error #define ESYSERR        2  //general sys error#define EAPPERR        3  //general application error            // EPROTO has been defined by std c#ifndef EPROTO#define EPROTO        121 //protocol error#endif#ifndef ENODATA#define ENODATA       122 //no data#endif            // Transport errors#define ECLOSED       11  //net closed#define ESCKERR       12  //socket error#define ENETBRK       13  //net broken#define EPACKAG       14  //invalid package#define EREQUES       15  //invalid request#define ERESPON       16  //invalid response#define EOPENPORT  17  //open port error#define EFTPACCEPT  18  //ftp accept error#ifndef ETIMEDOUT#define ETIMEDOUT     78  //timedout#endif            // login errors#define EUSER         21  //invalid user#define EPASSWD       22  //invalid password            // Operation errors#define ENOFILE       32  //file not found#define EBRKUSR       33  //broken by user            // DB errors#define EDBERR       1401 //DB error#define ESQL         1402 //invalid sql#ifndef DATANOTFOUND#define DATANOTFOUND 1403#endif           /**             * @brief  Connection Status Definition            */            typedef enum            {                UNCONNECT      = 0  //unconnect               ,CONNECTED       = 1  //connected            }EConnStatus;            /**             * Commands.             */#define P_CMD_NONE       0  //none#ifndef P_CMD_START#define P_CMD_START      1  //start#endif#ifndef P_CMD_STOP#define P_CMD_STOP       2  //stop#endif#ifndef P_CMD_SUSPEND#define P_CMD_SUSPEND    3  //suspend#endif#ifndef P_CMD_RESUME#define P_CMD_RESUME     4  //resume#endif            /**              * @brief CTP消息包类型             */            enum ECTPCommand            {                CTP_RES_OK = 2,            //成功响应                 CTP_RES_FAIL = 1,          //失败响应                CTP_CMD_USER = 3,          //鉴权请求(用户安全)                 CTP_CMD_PASS = 4,          //鉴权请求(密码安全)                CTP_CMD_PASV = 5,          //发送向CTP服务器请求一个数据传输端口的指令(PASV)                CTP_CMD_QUIT = 6,          //退出,断开控制传输连接                 CTP_CMD_CWD = 11,          //进入目录请求                CTP_CMD_PWD = 13,          //显示目录请求                CTP_CMD_MKDIR = 14,        //创建目录请求                CTP_CMD_LIST = 15,         //文件列表请求                CTP_CMD_GET = 23,          //获取文件请求                 CTP_CMD_PUT = 24,          //发送文件请求                 CTP_CMD_RENM = 25,         //文件改名请求                CTP_CMD_DELF = 27,         //删除远端文件                CTP_CMD_TIME = 28,         //取得远端文件最新修改时间                CTP_CMD_SIZE = 29,         //取得远端文件大小                CTP_DATA_FILE = 100        //文件内容数据或文件列表信息数据            };            /**              * @brief CTP长度相关常量定义             */                typedef enum {                    LEN_CTP_MESSAGE_HEAD = 8                        ,LEN_CTP_MESSAGE_BODY = 4096                        ,LEN_CTP_MESSAGE = 4104                        ,LEN_CTP_DATA_BUFFER = 4096                        ,LEN_USER = 65                        ,LEN_PASSWORD = 65                        ,LEN_FILE_DIR = 256                        ,LEN_FILE_PATH = 512                        ,LEN_ERR_MAXLEN = 512                        ,LEN_MAX_DIR_LEVEL = 20                        ,LEN_MAX_CMD_PARAM = 256,LEN_NET_FILE_DATE= 15                }ECTPLen;                /**                  * @brief Telnet错误定义                 */            typedef enum            {                LS_ERROR_APP_SOCKET_CREATE = 400  //创建SOCKET套接字失败                    ,LS_ERROR_APP_SOCKET_CONN = 401  //连接SOCKET套接字失败                    ,LS_ERROR_APP_SOCKET_SEND = 402  //SOCKET套接字发送失败                    ,LS_ERROR_APP_SOCKET_RECV = 403  //SOCKET套接字接收失败            }ETelnetError;            enum            {                IBAS_TELNET_PORT            =23                    ,IBAS_TELNET_BUF_LENGTH    =256                    ,IBAS_TELNET_COMMAND_LENGTH=1024                    ,IBAS_TELNET_RET_MSG_LENGTH=10240                    ,IBAS_TELNET_MAX_TRY_COUNT=200                    ,IBAS_TELNET_PROMPT_LENGTH=3                    ,IBAS_TELENT_TIMEOUT_SEC=1            };#define IBAS_TELNET_MACRO_LOGIN                        "login: "#define IBAS_TELNET_MACRO_PASSWORD                     "Password: "#define IBAS_TELNET_MACRO_LASTLOGIN                    "Last login:"#define IBAS_TELNET_MACRO_OPERSYSTEM_HP                "HP-UX"#define IBAS_TELNET_MACRO_OPERSYSTEM_AIX               "AIX"#define IBAS_TELNET_MARCO_TEST_LS                      "ls"#define IBAS_TELNET_MACRO_RETURN                       "\r\n"#define IBAS_TELNET_COMMAND_PROMPT                     "$"#define IBAS_TELNET_COMMAND_PROMPT1                    "You have mail"#define IBAS_TELNET_HP_ENV_DEFAULT                     0   //使用字符串提示符就可判断登录结束#define IBAS_TELNET_HP_ENV1                            1   //需要通过判断"You have mail"字符串来结束登录操作        }    }}#endif