100分,在线等待,修改了从网上copy的一个socket 类,但是在析构的时候出现错误,请高手帮我看看都有那些方面的问题

youngzi 2007-02-01 09:34:21
写了一个服务器端,里面有一个TListenThread类,在这个类里使用线程,在类析构的时候发现10038错误。

//类定义
class TListenThread
{
private:
WSAData wsaData;
struct sockaddr_in server;
fd_set FDS;
UINT m_Port;
char szTmp[256];//Error Message

protected:

public:
TListenThread(UINT m_PortA,bool CreateSuspended);
virtual ~TListenThread();
SOCKET m_Socket;

HANDLE m_ListenThreadHandle;
friend unsigned __stdcall ThreadProc(void* lpParam);//线程函数
void DoError();
void InitSocket();
void CreateListenSocket();
void SetListenSocket();
void BindListenSocket();
void ListenSocket();
bool bstop;
};

//类实现:
TListenThread::TListenThread(UINT m_PortA,bool CreateSuspended)
{
m_Socket=INVALID_SOCKET;
m_Port=m_PortA;
szTmp[0]='\0';
::ZeroMemory(&wsaData,sizeof(WSAData));
::ZeroMemory(&server,sizeof(struct sockaddr_in));
bstop=false;
//创建线程
HANDLE m_ListenThreadHandle=(HANDLE)_beginthreadex(NULL,0,ThreadProc,(void*)this,0,NULL);
}
//---------------------------------------------------------------------------
unsigned __stdcall ThreadProc(void* lpParam)//线程函数
{
TListenThread * p = (TListenThread *) lpParam;
char buf[4096];
struct sockaddr_in from; //for UDP
int nLen=sizeof(from),nSize=0; //for UDP
p->InitSocket();
p->CreateListenSocket();
p->SetListenSocket();
p->BindListenSocket();

p->ListenSocket();
struct sockaddr_in client;
int nLength=sizeof(struct sockaddr_in);
while(!p->bstop)
{
int nError=select(1,&(p->FDS),0,0,0);
//if(nError<=0) Terminate();
SOCKET m_AcceptSocket=accept(p->m_Socket,(struct sockaddr*)&client,&nLength);
if(m_AcceptSocket==INVALID_SOCKET)
{
sprintf(p->szTmp,"Failed to execute accept,error no:%d",::WSAGetLastError());
::MessageBox(0,p->szTmp,"Error",MB_OK+MB_ICONERROR);
p->DoError();
//Terminate();
return 0;
}
TCommunication *pCThread=new TCommunication(m_AcceptSocket,FALSE);
int i=1;
}

_endthreadex(0);

}
//---------------------------------------------------------------------------
TListenThread::~TListenThread()
{
closesocket(m_Socket);
::WSACleanup(); //这里出现10038错误
m_Socket=INVALID_SOCKET;
m_Port=0;
szTmp[0]='\0';
::ZeroMemory(&wsaData,sizeof(WSAData));
::ZeroMemory(&server,sizeof(struct sockaddr_in));

}
//----------------------------------------------------------------------------
void TListenThread::DoError()
{
if(m_Socket!=INVALID_SOCKET) closesocket(m_Socket);
WSACleanup();
return;
}
//----------------------------------------------------------------------------
void TListenThread::InitSocket()
{
WORD version=MAKEWORD(2,0);
if(::WSAStartup(version,&wsaData))
{
sprintf(szTmp,"Failed to intiailize socket,error no:%d",::WSAGetLastError());
::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);
DoError();
return;
}
}
//-------------------------------------------------------------------------------
void TListenThread::CreateListenSocket()
{
m_Socket=socket(AF_INET,SOCK_STREAM,0);

if(m_Socket==INVALID_SOCKET){
sprintf(szTmp,"Failed to create socket!");
::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);
DoError();
return;
}
}
//---------------------------------------------------------------------------
void TListenThread::SetListenSocket()
{
server.sin_family=AF_INET;
server.sin_port=htons(m_Port);
server.sin_addr.S_un.S_addr=INADDR_ANY;
int NewOpenType=SO_SYNCHRONOUS_NONALERT;
if(setsockopt(INVALID_SOCKET,SOL_SOCKET,SO_OPENTYPE,(char*)&NewOpenType,4))
{
sprintf(szTmp,"Set socket option error,error no:%d",::WSAGetLastError());
::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);
DoError();
return;
}
}
//-----------------------------------------------------------------------------
void TListenThread::BindListenSocket()
{
if(bind(m_Socket,(sockaddr*)&server,sizeof(struct sockaddr_in)))
{
sprintf(szTmp,"Failed to bind socket,error no:%d",::WSAGetLastError());
::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);
DoError();
return;
}

}
//-----------------------------------------------------------------------------
void TListenThread::ListenSocket()
{
if(listen(m_Socket,SOMAXCONN))
{
sprintf(szTmp,"listen error,error no:%d",::WSAGetLastError());
::MessageBox(0,szTmp,"Error",MB_OK+MB_ICONERROR);
DoError();
return;
}
//Determine whether there is any connection
FD_ZERO(&FDS);
FD_SET(m_Socket,&FDS);
}

请大家帮忙看看,如何把这个类改的没有错误?
...全文
374 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hhcjb 2007-02-08
  • 打赏
  • 举报
回复
内存泄露是没delete掉应该,逻辑问题,你该 检查程序先,接收数据什么方式?这个地方容易出现你说的这个现象的内存泄露
ouyh12345 2007-02-01
  • 打赏
  • 举报
回复
10038 在一个非套接字上尝试了一个操作。
DoError()里也执行了closesocket和WSACleanup.
看看析构之前是否执行了DoError
CppFile 2007-02-01
  • 打赏
  • 举报
回复
如果真是在析构里出错,应该是在这行:
closesocket(m_Socket);
原因会不会是在线程启动前,或者线程建立socket前,对象就已经被调用了析构函数?
//--------------------------------------------------------
不是这一句,是下面的那一句,::WSACleanup();
线程启动了,并且可以正常运行,但是退出的时候就出问题了
microyzy 2007-02-01
  • 打赏
  • 举报
回复
如果真是在析构里出错,应该是在这行:
closesocket(m_Socket);
原因会不会是在线程启动前,或者线程建立socket前,对象就已经被调用了析构函数?
CppFile 2007-02-01
  • 打赏
  • 举报
回复
我后来把主函数改为这样:
TListenThread * p = (TListenThread *) lpParam;
char buf[4096];
struct sockaddr_in from; //for UDP
int nLen=sizeof(from),nSize=0; //for UDP
p->InitSocket();
p->CreateListenSocket();
p->SetListenSocket();
p->BindListenSocket();

p->ListenSocket();
struct sockaddr_in client;
int nLength=sizeof(struct sockaddr_in);
while(!p->bstop)
{
int nError=select(1,&(p->FDS),0,0,0);
SOCKET m_AcceptSocket=accept(p->m_Socket,(struct sockaddr*)&client,&nLength);

if(m_AcceptSocket!=INVALID_SOCKET)
{
new TCommunication(m_AcceptSocket,FALSE);
//CloseHandle(pCThread);
}
}

_endthreadex(0);
CloseHandle(p->m_ListenThreadHandle);

析构不出错了,但是在运行的时候,客户端给server发消息,server的内存不断的增长,没有释放出来,是什么地方的问题呢?我查看了线程监视器,在运行过程中,一般有2个线程,只有在接到消息的时候,才多出线程,但是消息处理完毕后,又只有2个线程,那么内存泄露只能在listen类里了,在什么地方呢?
CppFile 2007-02-01
  • 打赏
  • 举报
回复
发现在closesocket的时候,select事件触发了,只是得到的socket是无效的,不过关闭socket,select为什么会触发呢?
oyljerry 2007-02-01
  • 打赏
  • 举报
回复
如上,不要重复关闭
hhcjb 2007-02-01
  • 打赏
  • 举报
回复
在程序退出时 accept 了一个INVALID_SOCKET 的socket,然后执行了DoError()提前关闭套结字,等析购时再次关闭就出错了,想这种accept最好是构建事件来处理。简单的话我觉得你accept失败不需要关闭套结字,把DoError()屏蔽掉
skywoodsky 2007-02-01
  • 打赏
  • 举报
回复
WSACleanup是必须和WSAStartup一一对应的

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧