套接字类错误

时间:2011-02-04 01:30:27

标签: c++

ListenSocket.h

    //  class does not contain WSASTARTUP () and WSACLEANUP ()

#ifndef LISTENTHREAD_H
#define LISTENTHREAD_H
#include "includes.h"
#include "LOGMSGs.h"

// 1, CListenSocket: class is used to create the listener thread local variable.
// This class can be reused. When you call Close () is closed, re-calling Open () the new listening port. But the system did not use the feature.
class   CListenSocket
{
public:
    // main method:
    // BIND each object only to a port.
    CListenSocket(u_short nPort, int nSndSize = 0);
    // to release SOCKET
    ~CListenSocket(){};
    // Create server listening SOCKET, specific options see the code. Fails to return false.
    bool    Open();     // call can be repeated
    // error return INVALID_SOCKET
    SOCKET  Accept(u_long & nClientIP);
    // repeated calls. Usually not, can be used to take the initiative to close the SOCKET.
    // close the re-call after Open () re-use the object.
    void    Close();        // call can be repeated
    bool    IsOpen() { return m_bState; }
    bool    Rebuild();
public:
    SOCKET  Socket() { return m_sockListen; }
protected:
    // main member variables:
    const u_short   m_nPort;
    const int       m_nSndBuf;
    SOCKET  m_sockListen;
    // network status is normal sign.
    // When the value is false that the object is not available. May not have Open (), may also be a network error.
    bool    m_bState;
    time_t  m_tCloseTime;       // SOCKET last closed the time delay for the automatic re-SOCKET
};



#endif  // LISTENTHREAD_H

ListenSocket.cpp

#include "ListenSocket.h"
long    s_nSocketCount = 0;
int     REBUILDLISTENDELAYSEC;

CListenSocket::CListenSocket(u_short nPort, int nSndBuf /*= 0*/)    // 0: Default
         : m_nPort(nPort), m_nSndBuf(nSndBuf)
{
    m_sockListen    = INVALID_SOCKET;
    m_bState        = false;
//  m_nPort         = nPort;
    m_tCloseTime    = 0;
}

//  Error returned INVALID_SOCKET
SOCKET  CListenSocket::Accept(u_long & nClientIP)
{
/*
    // Reconstruction SOCKET
    if(!m_bState)
    {
        if(clock() < m_tCloseTime + REBUILDLISTENDELAYSEC*CLOCKS_PER_SEC)
            return INVALID_SOCKET;
        else
        {
            LOGMSG("Anti-crash system start listening SOCKET [%d] re under construction...", m_nPort);
            if(Open())
            {
                LOGMSG("... listen SOCKET reconstruction success.");
                PrintText("Listen SOCKET [%d] failed to rebuild SOCKET success. Server continues to run in the ...", m_nPort);
            }
            else
            {
                Error("... listen SOCKET reconstruction has failed. Server will not accept new connections");
                PrintText("Listen SOCKET [%d] error, [%d] seconds after the re-SOCKET. Server continues to run in the ...", m_nPort, REBUILDLISTENDELAYSEC);        // nDelaySec);
            }
            m_tCloseTime = clock();
        }
    }
//*/
    if(!m_bState)
    {
        Error("ACCEPT inner exception a1");
        return INVALID_SOCKET;
    }

    // ACCEPT
    struct sockaddr_in  addr;
    memset(&addr, 0, sizeof(addr));
    int    len = sizeof(addr);
    SOCKET newsock = accept(m_sockListen, (sockaddr*)&addr, (int*)&len);        // receive to the other side of the map, you can use
#ifdef  PROFILE_X
            // Analysis Accept speed (cycle speed)
            const int   nTimes2 = ACCEPTPROFILESEC;     // Statistics once every 30 seconds the speed ACCEPT
            static  clock_t tNextTime2 = clock() + nTimes2 * CLOCKS_PER_SEC;    //? Only one monitor thread, no sharing violation
            static long nCount2 = 0;                                //? Only one monitor thread, no sharing violation
            if(clock() >= tNextTime2)
            {
                PrintText("Each [%d] seconds to execute a [%d] times Accept ()", nTimes2, InterlockedExchange(&nCount2, 0));
                tNextTime2 = clock() + nTimes2 * CLOCKS_PER_SEC;
            }
            else
            {
                InterlockedIncrement(&nCount2);
            }
#endif  // PROFILE
    if(newsock == INVALID_SOCKET)
    {
        // Network Error
        int err = WSAGetLastError();
        if(err != WSAEWOULDBLOCK)
        {
            PrintText("Listen SOCKET %d failed, %s seconds after the re-SOCKET.", m_nPort, REBUILDLISTENDELAYSEC);
            Error("Listen SOCKET [%d] failed [%d], [%s] seconds after the re-SOCKET.", m_nPort, err, REBUILDLISTENDELAYSEC);
            Close();
        }
        else
            Error("ACCEPT inner exception a2");
            return INVALID_SOCKET;
    }
    else
    {
        nClientIP = addr.sin_addr.S_un.S_addr;
        InterlockedIncrement(&s_nSocketCount);
    }

    // Check whether the SOCKET closed 
    fd_set  readmask;
    FD_ZERO(&readmask);
    FD_SET(newsock, &readmask);
    struct timeval  timeout = {0, 0};
/*
    char nTemp;
    if(select(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) 0, &timeout) 
            && recv(newsock, &nTemp, 1, MSG_PEEK) == 0)
    {
#ifdef  ALPHA_X
        LOGMSG("ACCEPT a new SOCKET is invalid .");
#endif
        closesocket(newsock);
        InterlockedDecrement(&s_nSocketCount);
        return INVALID_SOCKET;
    }
//else*/
//*
    fd_set  exceptmask;
    FD_ZERO(&exceptmask);
    FD_SET(newsock, &exceptmask);
    int ret = select(FD_SETSIZE, &readmask, (fd_set *) 0, (fd_set *) &exceptmask, &timeout);
    if(ret < 0)
    {
        Error("ACCEPT a new SOCKET is invalid . can't read");       // Not trigger
        closesocket(newsock);
        InterlockedDecrement(&s_nSocketCount);
        return INVALID_SOCKET;
    }
    else if(ret > 0)
    {
        if(FD_ISSET(newsock, &exceptmask))
        {
            LOGMSG("ACCEPT a new SOCKET is invalid.except");        // Not trigger
            closesocket(newsock);
            InterlockedDecrement(&s_nSocketCount);
            return INVALID_SOCKET;
        }
        else if(FD_ISSET(newsock, &readmask))
        {
            char nTemp;
            if(recv(newsock, &nTemp, 1, MSG_PEEK) == 0)
            {
#ifdef  ALPHA_X
                LOGMSG("ACCEPT a new SOCKET is invalid. recv==0");      // Not trigger
#endif
                closesocket(newsock);
                InterlockedDecrement(&s_nSocketCount);
                return INVALID_SOCKET;
            }
        }
    }
//*/
#ifdef  PROFILE_X
            // analysis Accept speed (received valid SOCKET)
            const int   nTimes = ACCEPTPROFILESEC;      // Statistics once every 10 seconds the speed ACCEPT
            static  clock_t tNextTime = clock() + nTimes * CLOCKS_PER_SEC;      //? Only one monitor thread, no sharing violation
            static long nCount  = 0;                            //? Only one monitor thread, no sharing violation
            if(clock() >= tNextTime)
            {
                LOGPROFILE("Port [%d] for every [%d] seconds, the successful implementation of the [%d] times Accept()", 
                            m_nPort, nTimes, InterlockedExchange(&nCount, 0));
                tNextTime = clock() + nTimes * CLOCKS_PER_SEC;
            }
            else
            {
                InterlockedIncrement(&nCount);
            }
#endif  // PROFILE

    return newsock;
}

Main.cpp的

#include "includes.h"
#include "IniFile.h"
#include "LOGMSGs.h"
#include "ListenSocket.h"

CListenSocket Sock(9985);
int main()
{
    Sock.Open();
    if(!Sock.Open())
    {
        Sock.Rebuild();
    }
    if(Sock.IsOpen())
        PrintText("okey");
    Sock.Socket();
    u_long ip;
    Sock.Accept(ip);
}

但是我总是遇到这个错误:接受内部异常a2而它应该工作任何线索为什么?

1 个答案:

答案 0 :(得分:0)

CListenSocket Sock(9985);
int main()
{
    Sock.Open();
    if(!Sock.Open())

/* I think you meant 'IsOpen()' */

    {
        Sock.Rebuild();
    }
    if(Sock.IsOpen())
        PrintText("okey");
    Sock.Socket();
    u_long ip;
    Sock.Accept(ip);
}

顺便提一下,这段代码确实读取搞笑。感觉就像一个没有特定目标的通用工具包。也许我错过了它,但是如果你只是编写了实际上需要的网络代码,那么我必须认为你会得到更好的结果,然后将公共位抽象成一些辅助例程。尝试制作全能和最终所有网络助手库是没有意义的,但制作可以摧毁常见案例的工具有很大的意义。

如果你知道你在做什么,请随意忽略最后一段:)但如果你刚开始,我想建议写一些较小的客户端和服务器,然后尝试编写你的抽象层。