如何写过Socket的服务端程序???支持多个客户端的同时连接请求。(高分请教) 用VC的CSocket类创建一个对象,然后Create(),使用Bind()和Listen()(仅TCP need),然后每个连接都会触发OnAccept函数(CSocket类中),在其中调用Accept(),即可得到一个连接,这个当然支持多个连接。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 补充一下,在OnAccept写如下代码CSocket* psocket=new CSocket();Accept(*psocket);用此Socket进行与客户间的通讯。建议监听socket和通讯socket使用CSocket的派生类。 直接使用以下函数:TCP:socket();bind();listen();accept()(阻塞监听);接收到连接后应创建线程,在其中阻塞调用read();UDP:socket();bind();recvfrom()(应在线程中,阻塞接受,循环,为零则已断)以上函数返回小于零则出错,详情见MSDN if(pWoker->Ready()) pWorker->Workin();在Workin中创建线程startdealpack()中调用pWorker->DealPackIn()bool CBankWorker::Ready(){ BOOL bRet; char szMsg[256]; char szNetwork[20], szNode[10]; UINT nPort;/*memset(szNetwork, 0, sizeof(szNetwork));strcpy(szNetwork, "123456");unsigned short crc=0;for(int i =0 ;i<strlen(szNetwork);i++) crc=updcrc(crc, szNetwork[i], MTT);sprintf(szNode, "%04x", crc);sprintf(szMsg, "CRC校验=[%s]", szNode);m_pModule->SendLogMsg(szMsg);return false;*/ bRet = m_ListenSocket.Create(); if(bRet == FALSE) { sprintf(szMsg, "创建SOCKET失败!"); m_pModule->SendLogAllMsg(szMsg, EML_ERROR); return false; } bRet = m_ListenSocket.Listen(m_pModule->GetPort()); if(bRet == FALSE) { sprintf(szMsg, "无法打开端口%d", m_pModule->GetPort()); m_pModule->SendLogAllMsg(szMsg, EML_ERROR); return false; } m_ListenSocket.GetLocalAddressString(szNetwork, szNode); if(m_ListenSocket.m_nAddressFamily == AF_IPX) { sprintf("%s开始在网络号[%s]节点[%s]端口[%d]上侦听连接请求...", szNetwork, szNode, m_pModule->GetPort()); } else sprintf(szMsg,"开始在IP[%s]端口[%d]上侦听连接请求...", szNetwork, m_pModule->GetPort()); m_pModule->SendLogMsg(szMsg); return true;}void CBankWorker::WorkIn(){ char szMsg[64]; SOCKET sSocket ; do { if(sSocket = WaitForPackIn() ) {// m_pModule->AddReqPackNum();// m_pModule->AddReqPackByte(); STransData transData; transData.sSocket = sSocket; transData.pWorker = this; CWinThread* pDealPackThread = AfxBeginThread( StartDealPack, &transData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); if( pDealPackThread ) { // m_pRequest->AddThread( m_pWinThreadIn->m_nThreadID ); m_pStatus->AddThread( pDealPackThread->m_nThreadID , NULL, 0, NULL, tsFREE ); pDealPackThread -> ResumeThread( ); if( m_pStatus->WaitForStatus( pDealPackThread->m_nThreadID, tsWORKING, 5000L ) == FALSE ) { sprintf( szMsg, "线程(ID=%ld)死锁,已被取消!", pDealPackThread->m_nThreadID ); m_pModule->SendLogAllMsg( szMsg , EML_ERROR ); ::TerminateThread( pDealPackThread->m_hThread, -1 ); } } } if(m_pRequest->WaitForRequest( m_pWinThreadIn->m_nThreadID, 0L ) == REQUEST_STOP ) { m_pRequest->AnswerRequest( m_pWinThreadIn->m_nThreadID ); break; } TRACE(" BankWorkerIn in Working..\n " ); }while( true );}void CBankWorker::WorkOut(){ CPack *pPack ; do { if( pPack = WaitForPackOut() ) { DealPackOut( pPack ) ; } if(m_pRequest->WaitForRequest( m_pWinThreadOut->m_nThreadID, 0L ) == REQUEST_STOP ) { m_pRequest->AnswerRequest( m_pWinThreadOut->m_nThreadID ); break; } TRACE(" BankWorkerOut in Working..\n " ); }while( true );}SOCKET CBankWorker::WaitForPackIn(){ char szMsg[256]; int nAddrlen; SOCKADDR addr; SOCKET newSocket = m_ListenSocket.Accept(&addr, &nAddrlen); //if(SOCKET_ERROR == newSocket) || INVALID_SOCKET == newSocket) if(INVALID_SOCKET == newSocket) { if(WSAGetLastError() == WSAEINTR) { sprintf(szMsg, "Socket侦听被中断"); m_pModule->SendLogAllMsg(szMsg); } else { sprintf(szMsg, "Socket接受连接出错,错误码=[%d]", WSAGetLastError()); m_pModule->SendLogAllMsg(szMsg, EML_ERROR); // sprintf(szMsg,"INVALID_SOCKET=[%d]SOCKET_ERROR=[%d]", INVALID_SOCKET, SOCKET_ERROR); // m_pModule->SendLogAllMsg(szMsg, EML_ERROR); } return NULL; } Sleep(50); return newSocket;}CPack* CBankWorker::WaitForPackOut(){ unsigned long ret = ::WaitForSingleObject( m_pModule->OutPackEvent() , m_lTimeOut ); if( ret == WAIT_TIMEOUT ) return (CPack*)0; return m_pModule->GetOutPackQueu()->GetPack();}bool CBankWorker::DealPackIn(SOCKET sSocket){ int nRet = -1; char szMsg[512]; char szBuff[BUFSIZE+1]; char szLocalAddress[20], szLocalNode[10]; char szRemoteAddress[20], szRemoteNode[10]; UINT nPort; char szFunctionNo[4+1];// char szMac[9];// char szMacKey[17]; struct BSC_ErrorReturn ErrorPack; SLSocket serSocket(AF_INET);// CLock lock(&m_sect); char szMsgLogFile[81]; sprintf(szMsgLogFile, "./log/Brequest%04d.txt", GetLongDate()%10000);// CBankInfo BankInfo(m_pModule->GetLogin()->Dbproc()); TRACE(" CBankWorker::DealPackIn()..\n"); serSocket.SetTimeOut(m_pModule->GetBankTimeOut()*1000); serSocket.AttachSocket(sSocket); serSocket.GetLocalAddressString(szLocalAddress, szLocalNode); serSocket.GetRemoteAddressString(szRemoteAddress, szRemoteNode, &nPort); if(serSocket.m_nAddressFamily == AF_IPX) { sprintf(szMsg,"%s在本机网络号[%s]节点[%s]端口[%d]上侦听到网络号[%s]节点[%s]端口[%d]的一个请求...", szLocalAddress, szLocalNode, m_pModule->GetPort(), szRemoteAddress, szRemoteNode, nPort); } else sprintf(szMsg,"在本机IP[%s]端口[%d]上侦听到IP[%s]端口[%d]的一个请求...", szLocalAddress, m_pModule->GetPort(), szRemoteAddress, nPort); m_pModule->SendLogMsg(szMsg); 顶点法向量 与 面法向量 的概念 关于GDI的三个问题 菜鸟问题,为什么activeX控件显示不了 请教高手,如何列举出系统中所有的字符和汉字?在线等,马上给分! 一个mfc的问题,谢谢:) 很简单的一个问题,讲清楚就行! 关于文件存取的问题 为什么要学VC?????给分! 对话框中listctrl 控件不显示图象??/ 请问怎么样防止用户的恶意注册? 辅助进程得到一个数据,怎么能传到主进程?? 问一个和软件销售有关的问题
CSocket* psocket=new CSocket();
Accept(*psocket);
用此Socket进行与客户间的通讯。
建议监听socket和通讯socket使用CSocket的派生类。
TCP:socket();bind();listen();accept()(阻塞监听);接收到连接后应创建线程,在其中阻塞调用read();
UDP:socket();bind();recvfrom()(应在线程中,阻塞接受,循环,为零则已断)
以上函数返回小于零则出错,详情见MSDN
pWorker->Workin();
在Workin中创建线程startdealpack()中调用pWorker->DealPackIn()
bool CBankWorker::Ready()
{
BOOL bRet;
char szMsg[256];
char szNetwork[20], szNode[10];
UINT nPort;
/*
memset(szNetwork, 0, sizeof(szNetwork));
strcpy(szNetwork, "123456");
unsigned short crc=0;
for(int i =0 ;i<strlen(szNetwork);i++)
crc=updcrc(crc, szNetwork[i], MTT);
sprintf(szNode, "%04x", crc);
sprintf(szMsg, "CRC校验=[%s]", szNode);
m_pModule->SendLogMsg(szMsg);
return false;
*/
bRet = m_ListenSocket.Create();
if(bRet == FALSE)
{
sprintf(szMsg, "创建SOCKET失败!");
m_pModule->SendLogAllMsg(szMsg, EML_ERROR);
return false;
}
bRet = m_ListenSocket.Listen(m_pModule->GetPort());
if(bRet == FALSE)
{
sprintf(szMsg, "无法打开端口%d", m_pModule->GetPort());
m_pModule->SendLogAllMsg(szMsg, EML_ERROR);
return false;
} m_ListenSocket.GetLocalAddressString(szNetwork, szNode);
if(m_ListenSocket.m_nAddressFamily == AF_IPX)
{
sprintf("%s开始在网络号[%s]节点[%s]端口[%d]上侦听连接请求...",
szNetwork, szNode, m_pModule->GetPort());
}
else
sprintf(szMsg,"开始在IP[%s]端口[%d]上侦听连接请求...",
szNetwork, m_pModule->GetPort());
m_pModule->SendLogMsg(szMsg);
return true;
}
void CBankWorker::WorkIn()
{
char szMsg[64];
SOCKET sSocket ;
do
{
if(sSocket = WaitForPackIn() )
{
// m_pModule->AddReqPackNum();
// m_pModule->AddReqPackByte(); STransData transData;
transData.sSocket = sSocket;
transData.pWorker = this;
CWinThread* pDealPackThread = AfxBeginThread( StartDealPack, &transData, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
if( pDealPackThread )
{
// m_pRequest->AddThread( m_pWinThreadIn->m_nThreadID );
m_pStatus->AddThread( pDealPackThread->m_nThreadID , NULL, 0, NULL, tsFREE );
pDealPackThread -> ResumeThread( );
if( m_pStatus->WaitForStatus( pDealPackThread->m_nThreadID, tsWORKING, 5000L ) == FALSE )
{
sprintf( szMsg, "线程(ID=%ld)死锁,已被取消!", pDealPackThread->m_nThreadID );
m_pModule->SendLogAllMsg( szMsg , EML_ERROR );
::TerminateThread( pDealPackThread->m_hThread, -1 );
}
}
}
if(m_pRequest->WaitForRequest( m_pWinThreadIn->m_nThreadID, 0L ) == REQUEST_STOP )
{
m_pRequest->AnswerRequest( m_pWinThreadIn->m_nThreadID );
break;
}
TRACE(" BankWorkerIn in Working..\n " );
}while( true );
}void CBankWorker::WorkOut()
{
CPack *pPack ;
do
{
if( pPack = WaitForPackOut() )
{
DealPackOut( pPack ) ;
}
if(m_pRequest->WaitForRequest( m_pWinThreadOut->m_nThreadID, 0L ) == REQUEST_STOP )
{
m_pRequest->AnswerRequest( m_pWinThreadOut->m_nThreadID );
break;
}
TRACE(" BankWorkerOut in Working..\n " );
}while( true );
}SOCKET CBankWorker::WaitForPackIn()
{ char szMsg[256];
int nAddrlen;
SOCKADDR addr;
SOCKET newSocket = m_ListenSocket.Accept(&addr, &nAddrlen);
//if(SOCKET_ERROR == newSocket) || INVALID_SOCKET == newSocket)
if(INVALID_SOCKET == newSocket)
{
if(WSAGetLastError() == WSAEINTR)
{
sprintf(szMsg, "Socket侦听被中断");
m_pModule->SendLogAllMsg(szMsg);
}
else
{
sprintf(szMsg, "Socket接受连接出错,错误码=[%d]", WSAGetLastError());
m_pModule->SendLogAllMsg(szMsg, EML_ERROR);
// sprintf(szMsg,"INVALID_SOCKET=[%d]SOCKET_ERROR=[%d]", INVALID_SOCKET, SOCKET_ERROR);
// m_pModule->SendLogAllMsg(szMsg, EML_ERROR);
}
return NULL;
}
Sleep(50);
return newSocket;
}CPack* CBankWorker::WaitForPackOut()
{
unsigned long ret = ::WaitForSingleObject( m_pModule->OutPackEvent() , m_lTimeOut );
if( ret == WAIT_TIMEOUT ) return (CPack*)0;
return m_pModule->GetOutPackQueu()->GetPack();
}bool CBankWorker::DealPackIn(SOCKET sSocket)
{
int nRet = -1;
char szMsg[512];
char szBuff[BUFSIZE+1];
char szLocalAddress[20], szLocalNode[10];
char szRemoteAddress[20], szRemoteNode[10];
UINT nPort; char szFunctionNo[4+1];
// char szMac[9];
// char szMacKey[17]; struct BSC_ErrorReturn ErrorPack;
SLSocket serSocket(AF_INET);
// CLock lock(&m_sect);
char szMsgLogFile[81]; sprintf(szMsgLogFile, "./log/Brequest%04d.txt", GetLongDate()%10000);
// CBankInfo BankInfo(m_pModule->GetLogin()->Dbproc()); TRACE(" CBankWorker::DealPackIn()..\n"); serSocket.SetTimeOut(m_pModule->GetBankTimeOut()*1000);
serSocket.AttachSocket(sSocket);
serSocket.GetLocalAddressString(szLocalAddress, szLocalNode);
serSocket.GetRemoteAddressString(szRemoteAddress, szRemoteNode, &nPort);
if(serSocket.m_nAddressFamily == AF_IPX)
{
sprintf(szMsg,"%s在本机网络号[%s]节点[%s]端口[%d]上侦听到网络号[%s]节点[%s]端口[%d]的一个请求...",
szLocalAddress, szLocalNode, m_pModule->GetPort(), szRemoteAddress, szRemoteNode, nPort);
}
else
sprintf(szMsg,"在本机IP[%s]端口[%d]上侦听到IP[%s]端口[%d]的一个请求...",
szLocalAddress, m_pModule->GetPort(), szRemoteAddress, nPort); m_pModule->SendLogMsg(szMsg);