这个问题有点菜.我在对话框里有两个按扭, 一个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;
}

解决方案 »

  1.   

    注: 只能X掉窗口才可以结果, 按STOP键没有用, 进入不到那个程序
      

  2.   

    简单一句话: accept后面的 AfxMessageBox("accept end");
    这条语句绝不出现, 为什么?
      

  3.   

    accept是阻塞的,程序停在了该处,当有连接的时候才会往下执行。
      

  4.   

    OK, 我猜测也是这个问题, 那么有没有办法从外部中止这个ACCEPT?
      

  5.   

    谢: PiggyXP(【小猪】●你的说话是对的, 我看了一篇文章:http://www.yesky.com/SoftChannel/72342371928702976/20020910/1629711_1.shtmllisten(sock,1);
    //开启线程避免主程序的阻塞
    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()函数便是实现网络事件异步选择的核心函数。
      

  6.   

    对,因为windows程序都带UI,所以监听应该放到线程里,否则UI会死。但是楼主的问题是不是因为这个问题造成的呢?看楼主的口气好像stop按键是可以响应的。