这个问题有点菜.我在对话框里有两个按扭, 一个OK, 一个STOP. OK按了启动SOCKET, 按STOP停止, 但是我的控制始终进入不到程序, 高手看看, 什么环节错了!void CMyTest7Dlg::OnOK()
{
GetDlgItem(IDC_STATIC1)->SetWindowText("Start..."); WORD sockVersion;
WSADATA wsaData; sockVersion = MAKEWORD(1,1);
//start dll
int nRc = WSAStartup(sockVersion, &wsaData) ;
if ( nRc == WSASYSNOTREADY )
{
AfxMessageBox("System not ready!");
return ;
}
else if ( nRc == WSAVERNOTSUPPORTED )
{
AfxMessageBox("Socket Version not support!");
return ;
}
else if ( nRc == WSAEINPROGRESS )
{
AfxMessageBox("A blocking Windows Sockets 1.1 operation is in progress!");
return ;
} MySocketServer(); WSACleanup();
}void CMyTest7Dlg::OnStop()
{
AfxMessageBox("Stop");
GetDlgItem(IDC_STATIC1)->SetWindowText("");
m_bFlag = false;
WSACleanup();
}
short CMyTest7Dlg::MySocketServer()
{
SOCKET sListen, sClient;
struct sockaddr_in local, client; CWinThread* hThread;
char szmsg[200];
//char szbuff[2048]; sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if ( sListen == SOCKET_ERROR)
{
sprintf(szmsg, "socket() failed! Error: %d", WSAGetLastError());
AfxMessageBox(szmsg);
return 1; }
if ( sListen == INVALID_SOCKET)
{
sprintf(szmsg, "Failed socket()");
AfxMessageBox(szmsg);
WSACleanup();
//return SERVER_SOCKET_ERROR;
return 1;
} local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(8888); if ( bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
sprintf(szmsg, "socket() failed! Error: %d", WSAGetLastError());
AfxMessageBox(szmsg);
return 1;
} listen(sListen, SOMAXCONN);
while(m_bFlag)
{
int iAddrSize = sizeof(client);
//AfxMessageBox("accept");
sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
AfxMessageBox("accept end"); if ( sClient == INVALID_SOCKET)
{
Sleep(10);
continue;
}
sprintf(szmsg, "Accepted client: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
AfxMessageBox(szmsg); m_ThreadData.hDoneWnd=m_hWnd;
m_ThreadData.nData = 123; hThread = AfxBeginThread(HandleLink, &m_ThreadData, THREAD_PRIORITY_NORMAL, 0, 0, NULL); if ( hThread == NULL )
{
Sleep(10);
continue;
}
CloseHandle(hThread);
}
closesocket(sListen);
//WSACleanup();
return 0;
}
{
GetDlgItem(IDC_STATIC1)->SetWindowText("Start..."); WORD sockVersion;
WSADATA wsaData; sockVersion = MAKEWORD(1,1);
//start dll
int nRc = WSAStartup(sockVersion, &wsaData) ;
if ( nRc == WSASYSNOTREADY )
{
AfxMessageBox("System not ready!");
return ;
}
else if ( nRc == WSAVERNOTSUPPORTED )
{
AfxMessageBox("Socket Version not support!");
return ;
}
else if ( nRc == WSAEINPROGRESS )
{
AfxMessageBox("A blocking Windows Sockets 1.1 operation is in progress!");
return ;
} MySocketServer(); WSACleanup();
}void CMyTest7Dlg::OnStop()
{
AfxMessageBox("Stop");
GetDlgItem(IDC_STATIC1)->SetWindowText("");
m_bFlag = false;
WSACleanup();
}
short CMyTest7Dlg::MySocketServer()
{
SOCKET sListen, sClient;
struct sockaddr_in local, client; CWinThread* hThread;
char szmsg[200];
//char szbuff[2048]; sListen = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
if ( sListen == SOCKET_ERROR)
{
sprintf(szmsg, "socket() failed! Error: %d", WSAGetLastError());
AfxMessageBox(szmsg);
return 1; }
if ( sListen == INVALID_SOCKET)
{
sprintf(szmsg, "Failed socket()");
AfxMessageBox(szmsg);
WSACleanup();
//return SERVER_SOCKET_ERROR;
return 1;
} local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_family = AF_INET;
local.sin_port = htons(8888); if ( bind(sListen, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
{
sprintf(szmsg, "socket() failed! Error: %d", WSAGetLastError());
AfxMessageBox(szmsg);
return 1;
} listen(sListen, SOMAXCONN);
while(m_bFlag)
{
int iAddrSize = sizeof(client);
//AfxMessageBox("accept");
sClient = accept(sListen, (struct sockaddr *)&client, &iAddrSize);
AfxMessageBox("accept end"); if ( sClient == INVALID_SOCKET)
{
Sleep(10);
continue;
}
sprintf(szmsg, "Accepted client: %s:%d\n", inet_ntoa(client.sin_addr), ntohs(client.sin_port));
AfxMessageBox(szmsg); m_ThreadData.hDoneWnd=m_hWnd;
m_ThreadData.nData = 123; hThread = AfxBeginThread(HandleLink, &m_ThreadData, THREAD_PRIORITY_NORMAL, 0, 0, NULL); if ( hThread == NULL )
{
Sleep(10);
continue;
}
CloseHandle(hThread);
}
closesocket(sListen);
//WSACleanup();
return 0;
}
这条语句绝不出现, 为什么?
//开启线程避免主程序的阻塞
AfxBeginThread(Server,NULL);
……
UINT Server(LPVOID lpVoid)
{
……
int nLen=sizeof(SOCKADDR);
pView->newskt=accept(pView->sock,(LPSOCKADDR)& pView->sockin,(LPINT)& nLen);
……
WSAAsyncSelect(pView->newskt,pView->m_hWnd,WM_SOCKET_MSG,FD_READ|FD_CLOSE);
return 1;
}
这里之所以把accept()放到一个线程中去是因为在执行到该函数时如没有客户连接服务器的请求到来,服务器就会停在accept语句上等待连接请求的到来,这势必会引起程序的阻塞,虽然也可以通过设置套接字为非阻塞方式使在没有客户等待时可以使accept()函数调用立即返回,但这种轮询套接字的方式会使CPU处于忙等待方式,从而降低程序的运行效率大大浪费系统资源。考虑到这种情况,将套接字设置为阻塞工作方式,并为其单独开辟一个子线程,将其阻塞控制在子线程范围内而不会造成整个应用程序的阻塞。对于网络事件的响应显然要采取异步选择机制,只有采取这种方式才可以在由网络对方所引起的不可预知的网络事件发生时能马上在进程中做出及时的响应处理,而在没有网络事件到达时则可以处理其他事件,这种效率是很高的,而且完全符合Windows所标榜的消息触发原则。前面那段代码中的WSAAsyncSelect()函数便是实现网络事件异步选择的核心函数。