开发者 发表于 2007-12-24 17:11:34

socket关不掉吗?

我在Proactor下继承ACE_Service_Handler写了一个类Test(对象pTest),去连接另外一台机器;当去连接的时候会创建一个Test的实例pTest,可是在这个socket(也就是pTest)主动断开连接的时候,总是会出现程序挂掉的情况,请问有没有知道什么原因的!

是ACE对断开的连接有什么限制吗?

peakzhang 发表于 2007-12-24 23:08:48

你程序的问题,设置断点追踪一下。
ACE对断开的连接都是可以处理的,问题在于你怎么处理。

开发者 发表于 2007-12-25 10:43:53

我在程序跟踪的过程中,在delete pTest的时候,里面有一个指针总是在delete的时候有问题,好像有越位的情况,是不是程序里面有什么地方指针或者其他的东西使用不当造成的?

winston 发表于 2007-12-25 11:02:57

这是很常见的C++程序错误,你删除指针指向的对象的时候,这个对象还在被别的线程操作。
应该是典型的同步问题。

开发者 发表于 2007-12-25 12:47:03

所有程序都是在一个Thread里面跑的

winston 发表于 2007-12-25 12:57:50

那就更好查了。贴上程序,我们帮你分析分析。

开发者 发表于 2007-12-25 14:12:58

外面在使用的时候是
CTestA *pTest = new CTestA();
pTest.Connect();

delete的时候是:
pTest.DisConnect();
delete pTest;//问题就再这里,总是delete的时候错误,甚至导致程序挂掉
pTest = 0;

开发者 发表于 2007-12-25 14:13:28

下面是代码:
CTestA::CTestA()
{
      pSoc                = 0;
}

CTestA::~CTestA()
{
      if (pSoc)
      {
                delete pSoc;
                pSoc = 0;
      }
}

bool CTestA::Connect()
{
      ACE_Asynch_Connector<CTestB> vConnector;
      vConnector.open();
      ACE_INET_Addr peer_addr (8000, 192.168.1.10);
      if (vConnector.connect(peer_addr, (const ACE_INET_Addr &)ACE_Addr::sap_any, 1, this) == -1)
      {
                return false;
      }
      return true;
}

bool CTestA:isConnect()
{
      if (!pSoc)
                return false;

      if (pSoc->handle() != ACE_INVALID_HANDLE)
                ACE_OS::closesocket (pSoc->handle());

      if (pSoc)
      {
                pSoc->m_pTestA = 0;
                delete pSoc;
                pSoc = 0;
      }

      return true;
}

void CTestA::MethodA(void* pSocket)
{
      if (!pSocket) return;
      pSoc = (CTestB*) pSocket;

      ACE_OS::memset(cBuffer, 0, 1024);//cBuffer成员变量
}

void CTestA::MethodB()
{
      if (!pSoc) return;

      ACE_CString str = "ddddddddddddddddddd";
      pSoc->ostWrite((char*)str.fast_rep(), str.length());
}

void CTestA::MethodC(char *pContent, int nSize)
{
      //
}

void CTestA::CloseA()
{
      pSoc = 0;
}


CTestB继承ACE_Service_Handler
CTestB::CTestB()
{
      m_pTestA      = 0;
      m_pReaderMB                = 0;
}

CTestB::~CTestB()
{
      if (m_pTestA)
      {
                m_pTestA->CloseA();
                m_pTestA = 0;
      }

      if (this->handle() != ACE_INVALID_HANDLE)
                ACE_OS::closesocket (this->handle());

      if (m_pReaderMB)
      {
                m_pReaderMB->release();
                m_pReaderMB = 0;
      }
}

void CTestB::act (const void *pTest)
{
      m_pTestA = (CTestA*)pTest;
      if (m_pTestA)
                m_pTestA->MethodA(this);
}

void CTestB:pen (ACE_HANDLE h, ACE_Message_Block&)
{
      if (!m_pTestA)
      {
                delete this;
                return;
      }

      this->handle (h);
      if (this->m_Reader.open (*this) != 0 || this->m_Writer.open (*this) != 0)
      {
                delete this;
                return;
      }

      ACE_NEW_NORETURN (m_pReaderMB, ACE_Message_Block (PACKET_BUFFERSIZE));

      if (m_pTestA)
                m_pTestA->MethodB();

      PostRead();
}

void CTestB::handle_read_stream(const ACE_Asynch_Read_Stream::Result &result)
{
      if (!result.success () || result.bytes_transferred () == 0)
      {
                delete this;
                return;
      }

      ACE_Message_Block &mb = result.message_block();

      if (m_pTestA)
                m_pTestA->MethodC(mb.rd_ptr(), mb.length());

      PostRead();
}

void CTestB::handle_write_stream(const ACE_Asynch_Write_Stream::Result &result)
{
      result.message_block().release();

      if (!result.success () || result.bytes_transferred () == 0)
      {
                delete this;
                return;
      }
      return;
}

void CTestB:ostRead()
{
      if (!m_pReaderMB) return;
      if (this->handle() == ACE_INVALID_HANDLE) return;

      m_pReaderMB->reset();
      if (this->m_Reader.read (*m_pReaderMB, m_pReaderMB->space()) != 0);
}

bool CTestB:ostWrite(char* pBuffer, int nSize)
{
      if (this->handle() == ACE_INVALID_HANDLE) return false;

      ACE_Message_Block* pWriterMB = 0;
      ACE_NEW_RETURN (pWriterMB, ACE_Message_Block (1024), false);

      pWriterMB->copy(pBuffer, nSize);
      if (this->m_Writer.write (*pWriterMB, pWriterMB->length ()) != 0);

      return true;
}


[ 本帖最后由 winston 于 2007-12-25 15:16 编辑 ]

winston 发表于 2007-12-25 15:19:36

pTest.DisConnect(); 怎么写的?

感觉是你的程序退出了,但是还有对象在操作导致。

开发者 发表于 2007-12-25 16:48:15

外面在使用的时候是
CTestA *pTest = new CTestA();
pTest.Connect();

delete的时候是:
pTest.isConnect();//打错了
delete pTest;//问题就再这里,总是delete的时候错误,甚至导致程序挂掉
pTest = 0;
页: [1] 2 3
查看完整版本: socket关不掉吗?