自己封装了一个socket,简要代码如下:(列出主要函数)
class MySocket{
public:
    MySocket();
    ~MySocket();
    BOOL CreateServer(int port, int backlog);
    BOOL StartServer();
    void Close();
    ....
protected:
     SOCKET m_hServer;
    ....    
    static DWORD CALLBACK ServerProc(LPVOID lpParm);
    ...
}MySocket()
{
       if(WSAStartup(0x202, &wsaData) == 0)
{
m_bWSAStartup = TRUE;
err = 0;
}
else
{
m_bWSAStartup = FALSE;
err = WSAGetLastError();
}
}BOOL MySocket::CreateServer(int port, int backlog)
{
if(m_bListened == TRUE) Close(); struct sockaddr_in local; //创建监听socket
    m_hServer = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if(m_hServer == SOCKET_ERROR)
    {
        err = WSAGetLastError();
        return FALSE;
    } //添参数
local.sin_addr.s_addr = htonl(INADDR_ANY);
    local.sin_family = AF_INET;
    local.sin_port = htons(port); if(bind(m_hServer, (struct sockaddr *)&local, sizeof(local)) == SOCKET_ERROR)
    {
err = WSAGetLastError();
closesocket(m_sServer);
        return FALSE;
    } //开始侦听
    if(listen(m_hServer, backlog) != 0)
{
err = WSAGetLastError();
closesocket(m_sServer);
        return FALSE;
    } m_nServerPort = port;
m_bListened = TRUE;
m_bNeedCloseServer = TRUE; return TRUE;
}
BOOL MySocket::StartServer()
{
if(!m_bListened) return -1;
if(m_hServer == NULL) return -1;        //开一个线程
m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); if(m_hServerThread == NULL)
{
delete para;
err = WSAGetLastError();
                return FALSE;
} return TRUE;
}DWORD CALLBACK MySocket::ServerProc(LPVOID lpParm)
{
SOCKET s = (SOCKET)lpParm;

SOCKET sClient;
int iAddrSize;
struct sockaddr_in addr;
char IP[32];
HANDLE hThread;
        DWORD dwThreadId;
DEALPARA *parac; iAddrSize = sizeof(addr); while(1)
{
                // 问题出在这里accept不阻塞,检查了返回值sClient 异常
sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize);
if(sClient == SOCKET_ERROR) break;
sprintf(IP, "%d.%d.%d.%d", addr.sin_addr.S_un.S_un_b.s_b1,     addr.sin_addr.S_un.S_un_b.s_b2,    addr.sin_addr.S_un.S_un_b.s_b3,    addr.sin_addr.S_un.S_un_b.s_b4);
//侦听到连接,开一个线程
                 hThread = CreateThread(NULL, 0, DealProc, (LPVOID)(sClient), 0, &dwThreadId); if(hThread == NULL) delete parac;
} return 0;
}建立socket后启动服务StartServer(),线程函数ServerProc中的accept不阻塞,为什么??

解决方案 »

  1.   

    sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize); 
    if(sClient == SOCKET_ERROR) break; =====================
    sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize); 
    if(sClient == INVALID_SOCKET) break; 
      

  2.   

    accept返回是失败吗?错误码是什么?SOCKET_ERROR与INVALID_SOCKET都是-1,写错了倒也没关系,不过最好还是区分开。
    另外iAddrSize = sizeof(addr);最好放在循环里面。
      

  3.   

    你检测一下--》
    ASSERT(s!=INVALID_SOCKET)sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize); 
    我估计你的服务器SOCKET根本没有成功监听,甚至在最开始可能WSASTART( )你都没有调用过
      

  4.   

    to cnzdgs:sClient = accept(s, (struct sockaddr *)&addr, &iAddrSize); 
    if(sClient == SOCKET_ERROR)

       int err = WSAGetLastError();
       break; 
    }程序调到当前行sClient = accept(...)时,不阻塞,sClient返回为一个很大的值 ,错误码err = 10038
      

  5.   

    to danscort2000:
    WSAStartup()在构造函数里已调用过了
    在调用accept函数前s是有值的,SOCKET已成功监听
      

  6.   

    主线程是不是在accept线程结束前退出了?
      

  7.   

    你调试一下程序,先确认CreateServer是否返回成功,另外注意创建线程时和accept时,socket的值是否有变化,还有,在你的程序中closesocket的地方设置断点,看看是不是被关闭了。
      

  8.   

    to unsigned:
    不太明白你的意思??
    我的主函数这样的:
    int main()
    {
    MySocket   server;
    BOOL       bServer;
    int        nPort = 80; memset(finfo.name, 0, NAME_LEN);

    if(server.CreateServer(nPort, SOMAXCONN))
    {
    bServer = server.StartServer();
    } return TRUE;
    }
      

  9.   

    最简单的方法
    加TRACE监视各线程的运行情况
    现在最大的嫌疑就是你的主SOCKET存在问题
    建议在调用前检测一下主SOCKET是否正常
      

  10.   

    BOOL MySocket::StartServer() 

    if(!m_bListened) return -1; 
    if(m_hServer == NULL) return -1; //开一个线程 
    m_hServerThread = CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); if(m_hServerThread == NULL) 

        delete para; 
        err = WSAGetLastError(); 
        return FALSE; 
    } return TRUE; } 
    我的StartServer函数在调用CreatThread后返回了,是不是这个问题啊,怎么解决?
    如何检测主SOCKET是否正常呢,我调试时调用accept前后主SOCKET的值没有变啊
      

  11.   

    主函数执行完就退出了,所以MySocket析构了。
      

  12.   

    int main() 

    MySocket*  server; 
    BOOL       bServer; 
    int        nPort = 80; memset(finfo.name, 0, NAME_LEN); server = (MySocket*)new MySocket;
    if(server->CreateServer(nPort, SOMAXCONN)) 

    bServer = server->StartServer(); 
    } return TRUE; 
    }
      

  13.   

    to cnzdgs:
    使用MySocket* server 还是有问题,我发现在到accept之前,主函数main已经返回了,所以MySocket构析了。
      

  14.   

    改成指针用new构造只要不delete就不会析构,主函数返回也没关系,可能是其它部分还有问题。你在程序中所有closesocket的地方设置断点来调试,看看是不是socket被关闭了。
      

  15.   

    主函数返回了,就算没析构,被你断在accepet那里了。
    主函数的线程销毁了,也会回收另外的线程和资源了。
      

  16.   

    to cnzdgs:
    用new构造了MySocket,在所有colsesocket设置了断点,都没有到那里,说明没有构析。
    qiangv说的有道理,应该是:主函数的线程销毁了,也会回收另外的线程和资源了。我在主线程m_hServerThread=CreateThread(NULL, 0, ServerProc, (LPVOID)(m_hServer ), 0, &dwThreadId); 后面加了WaitForSingleObject(m_hServerThread, INFINITE);让它等待,主函数的线程不销毁,accept就可以阻塞