2011-02-04 75 views
0

ListenSocket.hSocket类错误

// 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,同时它应该工作的原因为什么?

+0

在你的代码的哪个部分它错误 – Marlon 2011-02-04 01:45:29

+1

这是功课吗?否则,不要重新发明轮子。使用经过验证的网络库,如[Boost.Asio](http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/overview.html)。 – 2011-02-04 03:20:10

回答

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); 
} 

顺便说一句,这个代码肯定读取滑稽。这感觉就像一个通用工具包,没有考虑到具体的目标。也许我错过了它,但是我必须认为,如果你只写了实际上需要的网络代码,然后在普通位后面抽象出一些辅助例程,你会得到更好的结果。毫无意义地尝试制作全部和最终全部的网络帮助程序库,但在制作能够摧毁常见情况的工具方面存在巨大的问题。

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