//客户端线程,每一个客户链接创建一个线程处理
UINT ClientThread(LPVOID pParam)
{
myStruct* pMyStruct=(myStruct*)pParam;
SOCKET sockClient=pMyStruct->Socket;
HWND hWnd=pMyStruct->hWnd;
int nRet;
timeval timeout={0,200};
fd_set readfds={1,sockClient};
char szBuf[2049];
int nRecv;
while(1)
{
nRet=::select(0, &readfds,NULL,NULL,&timeout);//判断是否有数据
if(nRet>0){
memset(szBuf,0,2049);
nRecv=recv(sockClient,szBuf,2049,0);
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"接受到数据!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
if(nRecv<=0 || nRecv==SOCKET_ERROR )
{
break;//接受数据失败,关闭套接字,关闭线程
}
IN_MSG_HEADER *pHead=(IN_MSG_HEADER*)szBuf;
if(pHead->cmd==MSG_CONNECT_REQ) //请求包
{
IN_REGISTER_REQ* pReq=(IN_REGISTER_REQ*)szBuf;
int nRet1=strncmp(pReq->user,"admin",sizeof("admin"));
int nRet2=strncmp(pReq->password,"admin",sizeof("admin"));
static unsigned int no=0;
if(nRet1==0 && nRet2==0)
{
IN_REGISTER_RESP resp;
resp.hdr.cmd=MSG_CONNECT_RESP;
resp.hdr.length=sizeof(IN_REGISTER_RESP);
resp.hdr.seq_no=no++;
resp.hdr.type=CMD_TYPE_XUNFEI;
resp.result=0;
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"用户名密码正确!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
int nSend=send(sockClient,(char*)&resp,sizeof(resp),0);
if(nSend<sizeof(resp))
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答数据失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;//发送数据失败,关闭套接字,关闭线程
}
}
else{
IN_REGISTER_RESP resp;
resp.hdr.cmd=MSG_CONNECT_RESP;
resp.hdr.length=sizeof(IN_REGISTER_RESP);
resp.hdr.seq_no=no++;
resp.hdr.type=CMD_TYPE_XUNFEI;
resp.result=2;
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答用户名密码错误数据!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
int nSend=send(sockClient,(char*)&resp,sizeof(resp),0);
if(nSend<sizeof(resp))
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答用户名密码错误数据失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;//发送数据失败,关闭套接字,关闭线程
}
break;//非法用户或密码,关闭套接字,关闭线程
}
}
if(pHead->cmd==MSG_EVENT_NOTIFY)
{//正式的接受数据
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"接受到报警数据报!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
IN_EVENT_NOTIFY* pNotify=(IN_EVENT_NOTIFY*)szBuf;
int data=pNotify->data;
char description[256];
_snprintf(description,256,pNotify->description);
char syntax[256];
_snprintf(syntax,256,pNotify->syntax);
int type=pNotify->type;
int eventid=pNotify->event_id;
int eventtype=pNotify->evnet_type;
char* szDesc=new char[600];
memset(szDesc,0,600);
char szData[4];
if(data)
sprintf(szData,"报警");
else
sprintf(szData,"恢复");
sprintf(szDesc,"联动规则:%s_事件源类型:开关量_开关量:%s_状态:报警事件_描述:%s",syntax,szData,description);
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szDesc);
}
}
/*
if(nRet==SOCKET_ERROR)
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"socketClient错误!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;
}
*/
}
closesocket(sockClient);
return 0;
}//LoadWinsock用来装载和初始化Winsock,绑定本地地址,创建监听socket,等候客户端连接
UINT LoadWinsock(LPVOID lpParam)
{
CXFServerDlg* pDlg=(CXFServerDlg*)lpParam;
CString strIP;
int nPort=8000;
HWND hWnd;
strIP=pDlg->m_strIP;
nPort=pDlg->m_nPort;
hWnd=pDlg->m_hWnd; sockServer=socket(AF_INET,SOCK_STREAM,0);
if(sockServer==INVALID_SOCKET){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"创建SOCKET失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=inet_addr((LPCSTR)strIP);
addr.sin_port=htons(nPort);
if(bind(sockServer,(SOCKADDR*)&addr,sizeof(SOCKADDR))==SOCKET_ERROR){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"SOCKET绑定失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
if(listen(sockServer,5)==SOCKET_ERROR){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"SOCKET监听失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"开始监听!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
myStruct MyStruct;
while(1)
{
Sleep(2000);
SOCKADDR_IN addrClient;
int nSize=sizeof(addrClient);
SOCKET sockClient=accept(sockServer,(SOCKADDR*)&addrClient,&nSize);
if(INVALID_SOCKET==sockClient){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"接受SOCKET失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
closesocket(sockServer);
return 0;
}
char* szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"开始接受socketClient");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
MyStruct.Socket=sockClient;
MyStruct.hWnd=hWnd;
AfxBeginThread(ClientThread,&MyStruct);
}
closesocket(sockServer);
return 0;
}
//开始启动服务
void CXFServerDlg::OnBtnStart()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BTNSTART)->EnableWindow(FALSE);
GetDlgItem(IDC_BTNSTOP)->EnableWindow(TRUE);
UpdateData();
AfxBeginThread(LoadWinsock,this);
}
//显示服务日志
LRESULT CXFServerDlg::OnAddLog(WPARAM wParam,LPARAM lParam)
{
int nLine=m_list.GetCount();
if(nLine>20)
{
for (int i=0;i<nLine;i++)
{
m_list.DeleteString( i );
}
}
char* szLog;
szLog=(LPTSTR)lParam;
m_list.AddString(szLog);
delete[] szLog;
return 0;
}当客户端非法断开链接,怎样关闭套接字和客户线程;这段代码会占用100%的cpu,弄得我都不敢调试了!!
UINT ClientThread(LPVOID pParam)
{
myStruct* pMyStruct=(myStruct*)pParam;
SOCKET sockClient=pMyStruct->Socket;
HWND hWnd=pMyStruct->hWnd;
int nRet;
timeval timeout={0,200};
fd_set readfds={1,sockClient};
char szBuf[2049];
int nRecv;
while(1)
{
nRet=::select(0, &readfds,NULL,NULL,&timeout);//判断是否有数据
if(nRet>0){
memset(szBuf,0,2049);
nRecv=recv(sockClient,szBuf,2049,0);
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"接受到数据!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
if(nRecv<=0 || nRecv==SOCKET_ERROR )
{
break;//接受数据失败,关闭套接字,关闭线程
}
IN_MSG_HEADER *pHead=(IN_MSG_HEADER*)szBuf;
if(pHead->cmd==MSG_CONNECT_REQ) //请求包
{
IN_REGISTER_REQ* pReq=(IN_REGISTER_REQ*)szBuf;
int nRet1=strncmp(pReq->user,"admin",sizeof("admin"));
int nRet2=strncmp(pReq->password,"admin",sizeof("admin"));
static unsigned int no=0;
if(nRet1==0 && nRet2==0)
{
IN_REGISTER_RESP resp;
resp.hdr.cmd=MSG_CONNECT_RESP;
resp.hdr.length=sizeof(IN_REGISTER_RESP);
resp.hdr.seq_no=no++;
resp.hdr.type=CMD_TYPE_XUNFEI;
resp.result=0;
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"用户名密码正确!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
int nSend=send(sockClient,(char*)&resp,sizeof(resp),0);
if(nSend<sizeof(resp))
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答数据失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;//发送数据失败,关闭套接字,关闭线程
}
}
else{
IN_REGISTER_RESP resp;
resp.hdr.cmd=MSG_CONNECT_RESP;
resp.hdr.length=sizeof(IN_REGISTER_RESP);
resp.hdr.seq_no=no++;
resp.hdr.type=CMD_TYPE_XUNFEI;
resp.result=2;
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答用户名密码错误数据!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
int nSend=send(sockClient,(char*)&resp,sizeof(resp),0);
if(nSend<sizeof(resp))
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"发送回答用户名密码错误数据失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;//发送数据失败,关闭套接字,关闭线程
}
break;//非法用户或密码,关闭套接字,关闭线程
}
}
if(pHead->cmd==MSG_EVENT_NOTIFY)
{//正式的接受数据
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"接受到报警数据报!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
IN_EVENT_NOTIFY* pNotify=(IN_EVENT_NOTIFY*)szBuf;
int data=pNotify->data;
char description[256];
_snprintf(description,256,pNotify->description);
char syntax[256];
_snprintf(syntax,256,pNotify->syntax);
int type=pNotify->type;
int eventid=pNotify->event_id;
int eventtype=pNotify->evnet_type;
char* szDesc=new char[600];
memset(szDesc,0,600);
char szData[4];
if(data)
sprintf(szData,"报警");
else
sprintf(szData,"恢复");
sprintf(szDesc,"联动规则:%s_事件源类型:开关量_开关量:%s_状态:报警事件_描述:%s",syntax,szData,description);
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szDesc);
}
}
/*
if(nRet==SOCKET_ERROR)
{
char* szTip=new char[64];
memset(szTip,0,64);
sprintf(szTip,"socketClient错误!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szTip);
break;
}
*/
}
closesocket(sockClient);
return 0;
}//LoadWinsock用来装载和初始化Winsock,绑定本地地址,创建监听socket,等候客户端连接
UINT LoadWinsock(LPVOID lpParam)
{
CXFServerDlg* pDlg=(CXFServerDlg*)lpParam;
CString strIP;
int nPort=8000;
HWND hWnd;
strIP=pDlg->m_strIP;
nPort=pDlg->m_nPort;
hWnd=pDlg->m_hWnd; sockServer=socket(AF_INET,SOCK_STREAM,0);
if(sockServer==INVALID_SOCKET){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"创建SOCKET失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
SOCKADDR_IN addr;
addr.sin_family=AF_INET;
addr.sin_addr.S_un.S_addr=inet_addr((LPCSTR)strIP);
addr.sin_port=htons(nPort);
if(bind(sockServer,(SOCKADDR*)&addr,sizeof(SOCKADDR))==SOCKET_ERROR){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"SOCKET绑定失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
if(listen(sockServer,5)==SOCKET_ERROR){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"SOCKET监听失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
return 0;
}
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"开始监听!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
myStruct MyStruct;
while(1)
{
Sleep(2000);
SOCKADDR_IN addrClient;
int nSize=sizeof(addrClient);
SOCKET sockClient=accept(sockServer,(SOCKADDR*)&addrClient,&nSize);
if(INVALID_SOCKET==sockClient){
char *szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"接受SOCKET失败!");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
closesocket(sockServer);
return 0;
}
char* szLog=new char[256];
memset(szLog,0,256);
strcpy(szLog,"开始接受socketClient");
::PostMessage(hWnd,WM_ADDLOG,0,(LPARAM)szLog);
MyStruct.Socket=sockClient;
MyStruct.hWnd=hWnd;
AfxBeginThread(ClientThread,&MyStruct);
}
closesocket(sockServer);
return 0;
}
//开始启动服务
void CXFServerDlg::OnBtnStart()
{
// TODO: Add your control notification handler code here
GetDlgItem(IDC_BTNSTART)->EnableWindow(FALSE);
GetDlgItem(IDC_BTNSTOP)->EnableWindow(TRUE);
UpdateData();
AfxBeginThread(LoadWinsock,this);
}
//显示服务日志
LRESULT CXFServerDlg::OnAddLog(WPARAM wParam,LPARAM lParam)
{
int nLine=m_list.GetCount();
if(nLine>20)
{
for (int i=0;i<nLine;i++)
{
m_list.DeleteString( i );
}
}
char* szLog;
szLog=(LPTSTR)lParam;
m_list.AddString(szLog);
delete[] szLog;
return 0;
}当客户端非法断开链接,怎样关闭套接字和客户线程;这段代码会占用100%的cpu,弄得我都不敢调试了!!
解决方案 »
- vc2005中如何设置datagrid的列名?还有如何隐藏指定的列?
- 关于tab控件的一个问题
- 签约了
- 关于dll中的对话框播放flash的问题
- 我是新手,问一个很简单很简单的问题关于windows程序开发的
- google orkut邀请。
- 调用DELPHI的动态库需要传递一个无类型指针(Pointer),出现非法指针操作错误,请兄弟们帮忙看看代码。
- 对话框
- 使用ADO的Recordset如何得到第一个字段的值?函数是什么?谢谢
- Office2000的Office助手是怎么做出来的?大家谁知道?
- 求助:用过VC和sql2000做过东西的高手请进!存储过程调用EXE出错!
- listctrl表头的背景怎么设置?
当收到FD_CLOSE后进行处理
心跳信息,你用一个简单的S测试实际上 不一定要非法断开,正常连接的C都要 在长时间不 通信的情况下 K他
closesocket(sClient[nnCount]);
我的程序也遇到了你这样的情况,我就这样解决的。
不知道有没有更好的解决办法。
当nRecv==0时,则说明sockClient已经关闭了。MSDN解释:If no error occurs, recv returns the number of bytes received. If the connection has been gracefully closed, the return value is zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling