关于网络编程多线程死循环问题,我写一个聊天服务器程序,基于TCP的,
   WSADATA wsaData;
    if( WSAStartup(MAKEWORD(2,2),&wsaData)!=0)//初始化WSA  调用成功则返回0
{
MessageBox(NULL,"初始化失败","",MB_OK);
WSACleanup();
} SOCKET ServerSock = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);       //SOCK_STREAM 流式套接字
//IPPROTO_TCP TCP协议 用于流式套接字
if(INVALID_SOCKET ==ServerSock)
{
MessageBox(NULL,TEXT("创建套接字失败"),"",MB_OK);
WSACleanup();
}
sockaddr_in server;
server.sin_addr.S_un.S_addr = INADDR_ANY;   //本机ip
server.sin_family = AF_INET   ;               //指定通信协议
BOOL Err;
UINT Port =GetDlgItemInt(hwnd,IDC_PORT,&Err,TRUE);
server.sin_port = htons(Port);                    //主机字节顺序转成网络字节顺序
if(bind(ServerSock,(LPSOCKADDR)&server,sizeof(server))==SOCKET_ERROR)
{
MessageBox(NULL,TEXT("绑定套接字失败"),"",MB_OK);
closesocket(ServerSock);
} if(listen(ServerSock,5)==SOCKET_ERROR)
{
MessageBox(NULL,TEXT("监听失败"),"",MB_OK);
closesocket(ServerSock);
}

SetDlgItemText(hwnd,IDC_SYSTEMMSG,TEXT("服务器正在监听....."));
SOCKET TcpSocket;
SOCKADDR_IN TcpClientAddr;
while(1)
{
int alen;
TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
if(TcpSocket<0)
{
exit(1);
}
              ........
}
在上面的循环中为什么会出现死循环呢 我在这个循环中用accept不断接收连接请求,到底哪错了啊 

解决方案 »

  1.   

    if(TcpSocket<0)
    这个改成
    if (SOCKET_ERROR == TcpSocket)
    {
    exit(1);
    }
    试试。
      

  2.   

    if(TcpSocket<0)
    这个改成
    if (SOCKET_ERROR == TcpSocket)
    {
    break;
    }
    试试。
      

  3.   

    还是不行,界面死锁了,如果在循环中这样就可以
    while(true)
    {
    break;
    }
    但不能加任何东西,一加就死.
      

  4.   


    while(1)
    {
    SOCKET TcpSocket = INVALID_SOCKET;
    SOCKADDR_IN TcpClientAddr;
    int alen;
    TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
    if(TcpSocket == INVALID_SOCKET )
    {
    exit(1);
    }
    ........
    }
      

  5.   

    问题在于你的accept里面没有正确设置入口参数Length
    accept
    The Windows Sockets accept function accepts an incoming connection attempt on a socket.SOCKET accept (
      SOCKET s,                   
      struct sockaddr FAR* addr,  
      int FAR* addrlen            
    );
     
    Parameters

    [in] A descriptor identifying a socket that has been placed in a listening state with the listen function. The connection will actually be made with the socket that is returned by accept. 
    addr 
    [out] An optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family established when the socket was created. 
    addrlen 
    [out] An optional pointer to an integer that contains the length of the address addr. 
    SOCKET TcpSocket;
    SOCKADDR_IN TcpClientAddr;
    while(1)
    {
    int alen = sizeof(SOCKADDR_IN); // MUST INITIALIZE VALUE HERE!!!
    TcpSocket=accept(ServerSock,(SOCKADDR*)&TcpClientAddr,&alen);
    if(TcpSocket<0)
    {
    exit(1);
    }
    ........
    }
      

  6.   

    那样改了也不行,可能你们没明白我的意思。我建立的服务器有一个“BUTTON”,我想实现的功能是按下它,服务器就开始监听,然后我响应事件中添加代码,用一个死循环来不断接受用户的连接请求。但是问题出来了,一点BUTTON,界面马上死锁了,不知道是怎么回事。哪位兄弟帮帮我 留下邮箱,我把工程打包发过去,急啊,在此先谢过了。
      

  7.   

    你在循环里面加个 Sleep(100); 尝试一下。
    可能是循环一直在做, CPU没有时间去做其他事情了, 所以你的画面是死掉的现象。
      

  8.   

    那样改了也不行,可能你们没明白我的意思。我建立的服务器有一个“BUTTON”,我想实现的功能是按下它,服务器就开始监听,然后我响应事件中添加代码,用一个死循环来不断接受用户的连接请求。但是问题出来了,一点BUTTON,界面马上死锁了,不知道是怎么回事。哪位兄弟帮帮我 留下邮箱,我把工程打包发过去,急啊,在此先谢过了。当然你的界面会无响应啦,你的button按下事件这个处理函数都没有返回出来。你的accept函数也是阻塞的,没有接受到连接的话就一直停在这个语句
      

  9.   

    void Main_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
    {
        switch(id)
        {
            case IDC_OK://启动服务
    {
    WORD wVersionRequested;
    WSADATA wsaData;
    int err; wVersionRequested=MAKEWORD(2,2); err=WSAStartup(wVersionRequested,&wsaData);
    if(err!=0)
    {
    return;
    } if(LOBYTE(wsaData.wVersion)!=2||
    HIBYTE(wsaData.wVersion)!=2)
    {
    WSACleanup();
    return;
    } //创建用于监听的套接字
    SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0); SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
        addrSrv.sin_family=AF_INET;
    addrSrv.sin_port=htons(6000); bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));
    listen(sockSrv,5);

      
    SOCKADDR_IN addrClient;
    int len=sizeof(SOCKADDR);

    while(1)
    {
      //等待客户请求到来
    SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);
    char sendBuf[100];
    sprintf(sendBuf,"welcomee %s to http://www.sunxin.org",
           inet_ntoa(addrClient.sin_addr)); //发送数据
    send(sockConn,sendBuf,strlen(sendBuf)+1,0); char recvBuf[100];
    //接受数据
    recv(sockConn,recvBuf,100,0); MessageBox(NULL,recvBuf,TEXT(""),MB_OK);
    closesocket(sockConn);
    } }
            break;
            default:
    break;
        }
    }
    这是代码,IDC_OK为启动服务,我一点击就会执行上面的代码,然后界面就死了。有什么问题吗 
      

  10.   

    大体思路。
    button按下后开一个线程A负责监视客户端的连接。button事件结束。线程A在不断运行中。
    线程A一旦监视到一个连接。再针对这个连接开线程B,一个线程B只负责一个客户端的通信。
    可能开多个线程B所以, 要用一个LIST记住线程B的HANDLE(方便在最后关闭时,停止线程)。          A
          |  |  |  |......
          B  B  B  B......最后别忘记在程序终止时,停止所有以上开的线程。
      

  11.   

    有点儿意思哈哈,谢谢wenfengsoftware 
      

  12.   

    这是因为accept一直在那里接受连接,所以程序根本不往下执行,所以程序给人像是死了的感觉。如果你用了多线程,不会影响界面的响应。可以使用select来解决这个问题。
      

  13.   

    accept阻塞,建议开启线程