见如下代码
也可以接上帖看回顾
http://topic.csdn.net/u/20090514/17/e80f374b-24ff-4039-8dc2-0ac8180404bc.html?seed=769664972有问题,就是服务器异常断开,再正常开启后(我这里的客户端不关闭)
发送不成功时,关闭不了线程,while里一直做循环,界面出现假死状态_endthreadex(1);//关闭此线程也没有用
return 0;//返回没有用
发送错误时,就是关闭此线程,
if(closethread)
TerminateThread(hThread,0);//加了强制关闭怎么还是不行呢?
closethread=false;
m_hEvent=CreateEvent(NULL,TRUE,FALSE,"socketdll");//在这句前面加了三行,判断还是没有用, int OpenSocket(CString SerAddress,int SerPort,CString SendData)
{
if (m_hEvent)
{
WaitForSingleObject(m_hEvent,INFINITE);
ResetEvent(m_hEvent);
}
SendDataBuf=SendData; DWORD AIExitCode;
if(hThread && !closethread)
{
GetExitCodeThread(hThread,&AIExitCode);
if(AIExitCode==STILL_ACTIVE)
{
PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf);
return 1;
}
CloseHandle(hThread);
}
else
{
if(closethread)
TerminateThread(hThread,0);//这里的强制退出也没有用
closethread=false;
m_hEvent=CreateEvent(NULL,TRUE,FALSE,"socketdll");
hThread = (HANDLE)_beginthreadex(NULL,0,NewThread,0,0,&ThreadID);
if(hThread == 0)
{
CloseHandle(m_hEvent);
return 0;
}
Sleep(1);
PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf);
}
return 1;
}static unsigned WINAPI NewThread(void *arg)
{
if(SocketClose || StartEnv())
return 0; sockClient=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(QSerAddress);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(QSerPort);
if(INVALID_SOCKET == connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{//如果连接错误(对方IP或端口不正确),那么会阻塞20几秒才返回,暂时没有好的解决方案,可先发个ping包?
closesocket(sockClient);
WSACleanup();
return 0;
} int buflen = 0;
setsockopt(sockClient,SOL_SOCKET,SO_SNDBUF,(const char*)&buflen,sizeof(buflen));
MSG msg;
if(!SetEvent(m_hEvent))
{
return 1;
} while (1)
{
if(GetMessage(&msg,0,0,0))
{
switch(msg.message)
{
case WM_USERMSG:
CString *pStr = (CString*)msg.lParam;
if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0))
{
Sleep(10);
if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0))
{
closethread=true;//关闭标志位,好象没有用
closesocket(sockClient);
WSACleanup();
_endthreadex(1);//这里怎么退不出线程
return 0;//返回也没有用
}
}
pStr->ReleaseBuffer();
SetEvent(m_hEvent);
break;
}
}
Sleep(1000);
} closesocket(sockClient);
WSACleanup();
return 1;
}
也可以接上帖看回顾
http://topic.csdn.net/u/20090514/17/e80f374b-24ff-4039-8dc2-0ac8180404bc.html?seed=769664972有问题,就是服务器异常断开,再正常开启后(我这里的客户端不关闭)
发送不成功时,关闭不了线程,while里一直做循环,界面出现假死状态_endthreadex(1);//关闭此线程也没有用
return 0;//返回没有用
发送错误时,就是关闭此线程,
if(closethread)
TerminateThread(hThread,0);//加了强制关闭怎么还是不行呢?
closethread=false;
m_hEvent=CreateEvent(NULL,TRUE,FALSE,"socketdll");//在这句前面加了三行,判断还是没有用, int OpenSocket(CString SerAddress,int SerPort,CString SendData)
{
if (m_hEvent)
{
WaitForSingleObject(m_hEvent,INFINITE);
ResetEvent(m_hEvent);
}
SendDataBuf=SendData; DWORD AIExitCode;
if(hThread && !closethread)
{
GetExitCodeThread(hThread,&AIExitCode);
if(AIExitCode==STILL_ACTIVE)
{
PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf);
return 1;
}
CloseHandle(hThread);
}
else
{
if(closethread)
TerminateThread(hThread,0);//这里的强制退出也没有用
closethread=false;
m_hEvent=CreateEvent(NULL,TRUE,FALSE,"socketdll");
hThread = (HANDLE)_beginthreadex(NULL,0,NewThread,0,0,&ThreadID);
if(hThread == 0)
{
CloseHandle(m_hEvent);
return 0;
}
Sleep(1);
PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf);
}
return 1;
}static unsigned WINAPI NewThread(void *arg)
{
if(SocketClose || StartEnv())
return 0; sockClient=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr(QSerAddress);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(QSerPort);
if(INVALID_SOCKET == connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR)))
{//如果连接错误(对方IP或端口不正确),那么会阻塞20几秒才返回,暂时没有好的解决方案,可先发个ping包?
closesocket(sockClient);
WSACleanup();
return 0;
} int buflen = 0;
setsockopt(sockClient,SOL_SOCKET,SO_SNDBUF,(const char*)&buflen,sizeof(buflen));
MSG msg;
if(!SetEvent(m_hEvent))
{
return 1;
} while (1)
{
if(GetMessage(&msg,0,0,0))
{
switch(msg.message)
{
case WM_USERMSG:
CString *pStr = (CString*)msg.lParam;
if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0))
{
Sleep(10);
if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0))
{
closethread=true;//关闭标志位,好象没有用
closesocket(sockClient);
WSACleanup();
_endthreadex(1);//这里怎么退不出线程
return 0;//返回也没有用
}
}
pStr->ReleaseBuffer();
SetEvent(m_hEvent);
break;
}
}
Sleep(1000);
} closesocket(sockClient);
WSACleanup();
return 1;
}
解决方案 »
- formview上添加的控件在客户区中大小没变?
- 一个关于MFC的简单问题
- 怎样取得本机DWORD类型的子网掩码和网关?
- 【请教】如何编辑一个自己的类
- 初学乍练 vc中加入句柄时,报下面的错
- 请教高手一个问题(关于MFC)
- 问一个小问题,怎么添加DLL
- excelapplication控件???教教我吧,我不知道为什么?很简单的。
- 我在对话框中实现用回车键替代tab在编辑框中焦点的转换!
- 关于socket的小程序编译错误
- 我从codeproject下载了一个实例代码关于驱动开发的但是出现了一点问题可能是符号连接出现问题散分中...............
- 关于在2个不同进程里对话框效果显示的问题
这个循环中也要检测退出event,当发现触发了,就退出while,接着线程退出...
改为while(!closethread)还是不行,界面假死
在whilie(1)
{
if(bFlag)
return;
}
在while的循环体中判断某个标志等...当你想退出线程时设置bFlag = TRUE;
if(0 > send(sockClient,pStr->GetBuffer(0),pStr->GetLength()+1,0))
{
//closethread=true;//关闭标志位,好象没有用
//closesocket(sockClient);
//WSACleanup();
//_endthreadex(1);//这里怎么退不出线程
return 0;//---------------------->这里的返回也没有用,就在这死掉
}
眼睛一亮,精神抖擞,又快快乐乐地调程序去了^&^可现在调了还是很郁闷地说
加锁?可否给个小例子看看?还有,如果IP和端口错误,也会出现这情况(界面死了)
{
if(bFlag)
return;
}
这不是说的很清楚了么,就等于是一个P操作
{
if(GetMessage(&msg,0,0,0))
{
if (msg.message == WM_CLOSE)
{
break;
}
switch (msg.message)
///....
}
}
PostThreadMessage(ThreadID,WM_CLOSE,0,0);
这个方法不可以让线程退出................
PostThreadMessage(ThreadID,WM_USERMSG,0,(LPARAM)&SendDataBuf);
}
//此处可写日志
return 1;//返回不了,有问题,应该就是此处
}
............
这里比较奇怪,调用TerminateThread方法不行
用临界区把共用变量加锁
在外面:
CRITICAL_SECTION CriticalSection;
InitializeCriticalSectionAndSpinCount(&CriticalSection, INFINITE);
在whilie(1)
{
EnterCriticalSection(&CriticalSection);
if(bFlag)
return;
LeaveCriticalSection(&CriticalSection);
}
//dll里void CloseSocket()
{
SocketClose=true; //正常关闭socket
NewThreadClose=true; PostThreadMessage(ThreadID, WM_CLOSE, 0, 0); //加了这句
}
//exe里
void CTestSocketDlg::OnButton3()
{
// TODO: Add your control notification handler code here
typedef void (*close)();
close Closesocket;
Closesocket=(close)GetProcAddress(hInst,"CloseSocket");
Closesocket();
//FreeLibrary(hInst); //注释掉
SendCount=0;
GetDlgItem(IDC_IPADDRESS1)->EnableWindow(true);
GetDlgItem(IDC_EDIT1)->EnableWindow(true);
GetDlgItem(IDC_BUTTON1)->EnableWindow(true);
GetDlgItem(IDC_BUTTON2)->EnableWindow(false);
GetDlgItem(IDC_BUTTON3)->EnableWindow(false);
}
//其他一些地方小问题
void writelog(const char *Wlog)
{
FILE *pFile;
//strncpy(log_file,file_name1,sizeof(file_name));
// strcat(log_patch,"log_file.log");
pFile=fopen(log_patch,"a+");
if(NULL==pFile)
{
printf("Don't writer log file!");
//exit(-1); //第一次调试就飞在这里,退出明显不对啊,要返回
return;
}
//...
}
BYTE Qqueue[114]={"PS000000000ES000000000ES000000000ES000000000
ES000000000ES000000000ES000000000ES000000000ES000000000ES000000000E0D"};
// 存放队列LPCTSTR ReturnQueue()
{
CString tmpqueue;
tmpqueue.Format("%s",Qqueue);
return tmpqueue; //返回一个局部变量,函数执行完则释放,CSDN上见得最多的问题。要么直接返回CString对象,要么直接return (LPCSTR)Qqueue; 这个是全局变量,Free这个DLL之前不会被释放的。
}
如果再一次发送,发现无线程,就再开线程,有线程就直接发送
源码如下可下载
http://www.namipan.com/d/f68d60317bdbdbd5e52fe4a3176aaceefa68f111f1280700http://www.namipan.com/d/f68d60317bdbdbd5e52fe4a3176aaceefa68f111f1280700
我刚才试了下,断开后关闭线程只需在bool bExit=false;
while(1&&!bExit)
{
//判断出断开后
bExit = true;
}