err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ MessageBox(csError); exit(0); }
/* Confirm that the WinSock DLL supports 2.2.*/ /* Note that if the DLL supports versions greater */ /* than 2.2 in addition to 2.2, it will still return */ /* 2.2 in wVersion since that is the version we */ /* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { /* Tell the user that we could not find a usable */ /* WinSock DLL. */ WSACleanup(); csError.LoadString(IDS_STRINNETDLLERROR); MessageBox(csError,"Supply-代理",MB_OK|MB_ICONINFORMATION); exit(0); return; } err = GetPrivateProfileString("base" ,"outIp","127.0.0.1",m_csOutIp,sizeof(m_csLocalIP),m_sfilepath); err = GetPrivateProfileString("base" ,"LocalIP","127.0.0.1",m_csLocalIP,sizeof(m_csLocalIP),m_sfilepath); m_loutport = GetPrivateProfileInt("base","outport",444,m_sfilepath); m_lLocalport = GetPrivateProfileInt("base","Localport",444,m_sfilepath); m_hadMain = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(ThreadFuncSocketList),(void *)this,0,NULL); //////////记录///////// g_MainView->Message("启动代理!","成功","本地"); }DWORD WINAPI ThreadFuncSocketList( LPVOID lpParam ) { CSupplyView *pView = (CSupplyView *)lpParam;
OnReceive是callback函数,不是用户函数,因此,你是不能直接调用的.
你需要使用Receive来接收消息,但是,对于同步处理方式,在接受到消息之前,函数是不能够返回的,这就是为什么存在OnReceive的道理,当系统调用OnReceive的时候,标示有消息到达,在此时,你再调用Receive就好了!
UINT thread(LPVOID p)
{
char buff[100];
CSize size;
size.cx=0;
size.cy=30;
int s=1,msgcount,loop=1,flag=0;
CCSocketDlg *dlg=(CCSocketDlg*)AfxGetApp()->GetMainWnd();
//获得客户端数量
msgcount=dlg->getcount();
if (msgcount==-1)
loop=0;
if(loop)
{
s=1;
dlg->msgsock[msgcount]=accept(dlg->sock,(sockaddr*)&(dlg->serv),&(dlg->addlen));
if (dlg->msgsock[msgcount]==INVALID_SOCKET)
{
dlg->m_edit.SetWindowText("Error accept");
}
else
{
//启动线程
AfxBeginThread(thread,0);
dlg->SetForegroundWindow();
dlg->m_list.InsertItem(dlg->count++,"连接成功");
dlg->m_list.InsertItem(dlg->count++,inet_ntoa(dlg->serv.sin_addr));
dlg->m_list.Scroll(size);
dlg->m_button.EnableWindow(TRUE);
while(s!=SOCKET_ERROR)
{
//循环接收数据
s=recv(dlg->msgsock[msgcount],buff,100,0);
dlg->SetForegroundWindow();
if (s!=SOCKET_ERROR)
{
dlg->m_list.InsertItem(dlg->count++,buff);
dlg->m_list.Scroll(size);
dlg->sendtoall(dlg->msgsock[msgcount],buff);
}
} send(dlg->msgsock[msgcount],"Disconnected",100,0);
dlg->m_list.InsertItem(dlg->count++,"Disconnected");
dlg->m_list.Scroll(size);
dlg->msgsock[msgcount]=NULL;
for (int i=0;i<50;i++)
if (dlg->msgsock[i]!=NULL)
flag=1;
if (flag!=1)
dlg->m_button.EnableWindow(FALSE);
closesocket(dlg->msgsock[msgcount]);
}
}
//终止线程
AfxEndThread(0);
return 0;
}
比如说说:CScoket从创建到收发消息的整个调用函数的流程。
因为这是一个较简单的基对话框的客户端模拟器。
m_socket.SetRemoteHost (m_host);
m_socket.SetRemotePort (7000);vtHost.bstrVal = m_host.AllocSysString ();
vtPort.bstrVal = m_port.AllocSysString ();
m_socket.Connect (vtHost,vtPort);
//已经连接
m_socket.SendData (vtCommand);//发送然后在OnDataArrivalWinsock1函数中使用
m_socket.GetData(&vtData,vtType,vtMaxlen);
void CSupplyView::OnStartsupply()
{
// TODO: Add your command handler code here
if (m_bflag)
{
MessageBox("代理已经启用!","Supply-代理",MB_OK|MB_ICONINFORMATION);
return;
} m_nMode=1;
m_bflag=TRUE;
m_bT2C=TRUE;
m_bC2T=TRUE; CString sfile("IniSupply.ini");
CStdioFile inifile;
if (!inifile.Open(sfile,CFile::modeRead))
{
MessageBox("打开初始配置文件失败!","Supply-代理",MB_OK|MB_ICONINFORMATION);
return;
}
m_sfilepath=inifile.GetFilePath();
inifile.Close();
m_hadS = NULL ;
m_hadC = NULL ;
m_BList = 2; g_MainView = this ;
WORD wVersionRequested;
WSADATA wsaData;
CString csError;
csError.LoadString(IDS_STRINGERROR); memset(m_csOutIp,'\0',sizeof(m_csOutIp));
memset(m_csLocalIP,'\0',sizeof(m_csLocalIP)); csError = csError + ".....系统退出!";
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
MessageBox(csError);
exit(0);
}
/* Confirm that the WinSock DLL supports 2.2.*/
/* Note that if the DLL supports versions greater */
/* than 2.2 in addition to 2.2, it will still return */
/* 2.2 in wVersion since that is the version we */
/* requested. */
if ( LOBYTE( wsaData.wVersion ) != 2 ||
HIBYTE( wsaData.wVersion ) != 2 )
{
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
WSACleanup();
csError.LoadString(IDS_STRINNETDLLERROR);
MessageBox(csError,"Supply-代理",MB_OK|MB_ICONINFORMATION);
exit(0);
return;
} err = GetPrivateProfileString("base" ,"outIp","127.0.0.1",m_csOutIp,sizeof(m_csLocalIP),m_sfilepath);
err = GetPrivateProfileString("base" ,"LocalIP","127.0.0.1",m_csLocalIP,sizeof(m_csLocalIP),m_sfilepath); m_loutport = GetPrivateProfileInt("base","outport",444,m_sfilepath);
m_lLocalport = GetPrivateProfileInt("base","Localport",444,m_sfilepath); m_hadMain = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(ThreadFuncSocketList),(void *)this,0,NULL); //////////记录/////////
g_MainView->Message("启动代理!","成功","本地");
}DWORD WINAPI ThreadFuncSocketList( LPVOID lpParam )
{
CSupplyView *pView = (CSupplyView *)lpParam;
//////////记录/////////
g_MainView->Message("辅助控制线程创建","成功","本地");
if (-1==pView->InitSocktList())
{
AfxMessageBox("由于本地套接字原因,代理被禁用!",MB_OK|MB_ICONINFORMATION);
g_MainView->m_nMode=0;
g_MainView->Message("代理被禁用!","成功","本地");
return -1;
}
//AfxMessageBox("启动代理!",MB_OK|MB_ICONINFORMATION);
return 0;
}
{
// TODO: Add your command handler code here
m_nMode=0;
if (!m_bflag)
{
MessageBox("没有启用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
return;
}
m_bT2C=FALSE;
m_bC2T=FALSE; Sleep(1); CloseHandle(m_hadMain);
closesocket(m_SockList); CloseHandle(m_hadS);
CloseHandle(m_hadC);
if (m_SockConn != 0)
{
closesocket(m_SockConn);
}
m_bflag=FALSE;
}void CSupplyView::OnUpdateStartsupply(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(1==m_nMode);
}void CSupplyView::OnUpdateStopsupply(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
pCmdUI->SetRadio(0==m_nMode);
}void CSupplyView::OnConfig()
{
// TODO: Add your command handler code here
CString sfile("temporary.ini");
CStdioFile inifile;
if (!inifile.Open(sfile,CFile::modeWrite|CFile::typeText))
{
if (!inifile.Open(sfile,CFile::modeCreate|CFile::modeWrite|CFile::typeText))
{
AfxMessageBox("创建初始配置文件失败!");
return;
}
}
inifile.SeekToBegin();
CConfigDlg dlg;
if (dlg.DoModal()==IDOK)
{
inifile.WriteString("[base]\n");
inifile.WriteString("outIp=");
inifile.WriteString(dlg.m_soutip);
inifile.WriteString("\n");
inifile.WriteString("outport=");
inifile.WriteString(dlg.m_soutport);
inifile.WriteString("\n");
inifile.WriteString("Localport=");
inifile.WriteString(dlg.m_slocalport);
inifile.WriteString("\n");
inifile.WriteString("LocalIP=");
inifile.WriteString(dlg.m_slocalip);
inifile.WriteString("\n");
inifile.Flush();
inifile.Close();
CFile::Remove("IniSupply.ini");
inifile.Rename(sfile,"IniSupply.ini");
}
else
{
inifile.Close();
CFile::Remove(sfile);
}
}
/////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
BOOL CSupplyView::InitSocktList()
{
m_SockList = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if(m_SockList ==INVALID_SOCKET)
{
MessageBox("\nsocket() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
return -1;
} m_sadLocal.sin_addr.s_addr=htonl(INADDR_ANY);
m_sadLocal.sin_family=AF_INET;
m_sadLocal.sin_port=htons((unsigned short)m_lLocalport); if(bind(m_SockList,(struct sockaddr *)&m_sadLocal,sizeof(m_sadLocal))==SOCKET_ERROR)
{
MessageBox("\nbind() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
return -1;
}
//////////记录/////////
Message("创建本地套接字及绑定端口号","成功","本地"); SockList();
return 0;
}BOOL CSupplyView:: ConnectToServier()
{
long lError; m_SockConn = socket(AF_INET,SOCK_STREAM,IPPROTO_IP); if( m_SockConn ==INVALID_SOCKET)
{
MessageBox("\nsocket() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
return -1;
} m_sadRome.sin_addr.S_un.S_addr = inet_addr(m_csOutIp);
m_sadRome.sin_family=AF_INET;
m_sadRome.sin_port=htons((unsigned short)m_loutport); //////////记录/////////
g_MainView->Message("创建新套接字","成功","本地"); lError = connect(m_SockConn,(const struct sockaddr *)&m_sadRome,sizeof(m_sadRome)); if (lError != 0)
{
return -1 ;
} //////////记录/////////
g_MainView->Message("此套接字与服务器建立连接","成功","服务器--本地");
return TRUE;
}void CSupplyView::SockList()
{
int iAddrSize;
struct sockaddr Slave; if ( m_BList != 2)
{
return ;
}
m_BList = TRUE ; if ((!g_MainView->m_bC2T)||(!g_MainView->m_bT2C))
{
Message("强制禁用代理!","成功","本地");
MessageBox("强制禁用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
return;
} closesocket(m_SockConn);
closesocket(m_SockNew);
if (m_hadS != NULL)
{
CloseHandle(m_hadS);
m_hadS = NULL;
} if (m_hadC != NULL)
{
CloseHandle(m_hadC);
m_hadC = NULL ;
} iAddrSize=sizeof(Slave); if(listen(m_SockList,1)==SOCKET_ERROR)
{
MessageBox("\nlisten() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
} //////////记录/////////
Message("本地套接字启动监听","成功","本地");
int i=0;
while(i<=5)
{ m_SockNew = accept(m_SockList,(struct sockaddr *)&Slave,&iAddrSize);
if(m_SockNew == INVALID_SOCKET)
{
if ((!g_MainView->m_bC2T)||(!g_MainView->m_bT2C))
{
Message("强制禁用代理!","成功","本地");
MessageBox("强制禁用代理!","Supply-代理",MB_OK|MB_ICONINFORMATION);
return;
}
MessageBox("\naccept() failed","Supply-代理",MB_OK|MB_ICONINFORMATION);
}
else
{
//////////记录/////////
Message("通过本地套接字的接收,建立与CLIENT连接的新的套接字","成功","本地--客户端");
if (ConnectToServier() == TRUE )
{
m_SockArray1[0] = m_SockNew;
m_SockArray1[1] = m_SockConn; DWORD dwThreadID ,dwThreadID1;
m_hadS = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(TCPDataC2T),(LPVOID)&m_SockArray1[0],0,&dwThreadID);
Message("建立数据传输通道(客户端-->本地-->服务器)的辅助线程创建","成功","通道"); m_hadC = CreateThread(NULL,0,LPTHREAD_START_ROUTINE(TCPDataT2C),(LPVOID)&m_SockArray1[0],0,&dwThreadID1); Message("建立数据传输通道(服务器-->本地-->客户端)的辅助线程创建","成功","通道");
}
else
{
Message("代理被禁用!","成功","本地");
MessageBox("新套接字有错误,代理被禁用!","Supply-代理",MB_OK|MB_ICONINFORMATION);
}
}
}
m_BList = 0;
}#define BuffSize 80*1024 //缓冲区大小20k
{
int iRet,
ret=-1,//select 返回值 iSTCBCS=0;//STCBCS=SendToClientBuffCurrentSize
char szRecvFromTargetBuff[BuffSize]={0},
szSendToClientBuff[BuffSize]={0};
fd_set fdread,fdwrite; while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0],&fdwrite);
FD_SET(sock[1],&fdread);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
TRACE1("\n [服务器]select() failed:%d",GetLastError());
break;
} if(ret>0)
{
//sTarget可读,从target接收数据
if(FD_ISSET(sock[1],&fdread))
{
//接收target返回数据
iRet=recv(sock[1],szRecvFromTargetBuff,BuffSize,0);
if(iRet==SOCKET_ERROR)
{
TRACE1("\n [服务器]recv() from target failed:%d",GetLastError());
break;
}
else if(iRet==0)
break; g_MainView->Message("接收从服务器发送来的数据","成功","服务器-->本地");
//数据的认证过程,取得各种所需的数据,比较业务流水号的正确性
iRet=send(sock[0],szRecvFromTargetBuff,iRet,0); if(iRet==SOCKET_ERROR)
{
TRACE1("\n [服务器]recv() from target failed:%d",GetLastError());
break;
} g_MainView->Message("接收的数据从本地发往客户端","成功","本地-->客户端");
// afxDump << "[服务器]收到的字符串" << szRecvFromTargetBuff << "一共有 ="<< iRet << "\n" ; //清空接收target返回数据缓冲区
memset(szRecvFromTargetBuff,'\0',BuffSize);
//刷新发送到client的数据缓冲区当前大小
iSTCBCS+=iRet;
}
}//end of select ret
Sleep(1);
}//end of while
g_MainView->NewSockList();
return 0;
} //此函数负责从Client读取数据,然后转发给Target
DWORD WINAPI TCPDataC2T(SOCKET* sock)
{
int iRet,
ret=-1,//select 返回值
iSTTBCS=0;//STTBCS=SendToTargetBuffCurrentSize
char szSendToTargetBuff[BuffSize]={0},
szRecvFromClientBuff[BuffSize]={0};
fd_set fdread,fdwrite;
while(1)
{
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_SET(sock[0],&fdread);
FD_SET(sock[1],&fdwrite);
if((ret=select(0,&fdread,&fdwrite,NULL,NULL))==SOCKET_ERROR)
{
TRACE1("\n[客户端]select() failed:%d",GetLastError());
break;
}
if(ret>0)
{
//sClinet可读,client有数据要发送过来
if(FD_ISSET(sock[0],&fdread))
{
//接收sock[0]发送来的数据
iRet=recv(sock[0],szRecvFromClientBuff,BuffSize -1 ,0); if(iRet==SOCKET_ERROR)
{
TRACE1("\n[客户端]recv() from sock[0] failed:%d",GetLastError());
break;
}
else if(iRet==0)
break;
//此处需要处理获得时间,业务流水号,判断数据是否超过1400
//组包发送到防火墙代理模块
g_MainView->Message("接收从客户端发送过来的数据","成功","客户端-->本地");
iRet=send(sock[1],szRecvFromClientBuff,iRet,0); if (iRet == SOCKET_ERROR)
{
break ;
} g_MainView->Message("接收的数据从本地发往服务器","成功","本地-->服务器");
// afxDump << "[客户端]收到的字符串" << szRecvFromClientBuff << "一共有 ="<< iRet << "\n" ; //清空接收client数据的缓冲区
memset(szRecvFromClientBuff,'\0',BuffSize);
}
}//end of select ret
Sleep(1);
}//end of data send & recv循环
g_MainView->NewSockList();
return 0;
}void CSupplyView::NewSockList()
{
// afxDump << "进入新的NewSockList()\n";
{
m_BList ++ ;
SockList();
}
}void CSupplyView::Message(char *cmd, char *result,char *ADDRESS)
{
CListCtrl& mess=GetListCtrl();
int messcount=mess.GetItemCount();
if(messcount>2000)
mess.DeleteAllItems();
else
{
CString a;
int insertindex;
insertindex=mess.InsertItem(0,result);
mess.SetItem(insertindex,1,LVIF_TEXT,cmd,0,0,0,NULL);
mess.SetItem(insertindex,2,LVIF_TEXT,ADDRESS,0,0,0,NULL);
CTime t = CTime::GetCurrentTime();
a=t.Format("%Y-%m-%d %H:%M:%S");
mess.SetItem(insertindex,3,LVIF_TEXT,a,0,0,0,NULL);
}
}
这是我写的代理部分,我想对你有帮助的!
我发现不能进到OnReceive函数,到直接进入了OnClose了,为什么?
不过还是要谢谢各位:分照加