listener = socket(AF_INET, SOCK_STREAM, 0);
    if (listener < 0)
    {
        FatalError("socket() failed");
        return EXIT_FAILURE;
    }1、运行到这句的时候产生新的两个线程        newsocket = accept(listener,
                            (struct sockaddr *)&clientAddress,
                            &clientAddressLength)2、这句的时候产生新的两个线程,再次accept的时候,线程仍然保持不变(即不会新产生线程)对1、的理解是,对套接字是否默认产生2个线程?分别是读/写。但是监听的套接字只要一个读新的连接不就OK了吗?其中有做了什么其他操作吗对2、的理解是,服务器对客户端的连接是一对多的,但是都只执行读/写2个属性。那么这2个新线程就是负责服务器套接字从缓冲区读/写的工作。为了验证我的想法,我用冰刃来确认线程切换次数,但是不太准确。。有给出资料证明的100分敬上

解决方案 »

  1.   

    to  楼上怎么会不会呢?我是这样判断的:
    1。直接应用程序判断:先启动服务端,9个线程被创建(完成端口,创建线程是CPU数*2+2)然后启动客户端,3个线程,这个时候服务端线程数达到11个,继续开客户端,服务端线程不变2。跟踪判断
    如同我帖子里内容所发,创建套接字的时候,线程产生2个,在accept的时候,线程产生2个
    如果不明白我所说,建议看帖人做以下测试:
    一个普通的网络连接程序,线程是几个
    一个完成端口程序(创建线程是CPU数*2+2),总的线程数是多少。然后知出每个线程是干吗的
      

  2.   

    看看有没有高手知道吧,我的想法就是windows永远不会偷偷起线程来做事情,呵呵
      

  3.   

    后台自己起线程做事,这个没什么奇怪的,很多库会这么做,特别是异步函数,
    不过就你这个情况,没完整代码没法试,应该不是winsock库自己起的线程。
      

  4.   

    饿。就当做是业余机制探讨吧。代码很简单啊。普通的windows网络程序即可
      

  5.   

    如果你不主动创建线程,系统不会自动起线程。不同的网络程序实现的机制不同,因此“普通的网络程序”测试不出来通用的规则。例如说:我第一次写的用CAsyncSocket实现的,只有2个线程(因为我把socket单独放在一起)。而我后来用socket api实现,每个socket起2-3个线程我想楼主肯定是对socket某些机制异想天开了一点
      

  6.   

    你不能随便拿个程序测试,这证明不了你accept就会自动创建一个,因为人家程序确实可能用多线程实现。
    你自由自己写个干净的测试程序才能测试出来
      

  7.   

    我直接上干净的代码吧int _tmain(int argc, _TCHAR* argv[])
    {
        SOCKET  listener;
        SOCKET  newsocket;
        WSADATA WsaData;
        struct sockaddr_in serverAddress;
        struct sockaddr_in clientAddress;
        int     clientAddressLength;
        int     err;    CheckOsVersion();    err = WSAStartup (0x0101, &WsaData);
        if (err == SOCKET_ERROR)
        {
            FatalError("WSAStartup Failed");
            return EXIT_FAILURE;
        }    /*
         * Open a TCP socket connection to the server
         * By default, a socket is always opened
         * for overlapped I/O.  Do NOT attach this
         * socket (listener) to the I/O completion
         * port!
         */
        listener = socket(AF_INET, SOCK_STREAM, 0);
        if (listener < 0)
        {
            
            FatalError("socket() failed");
            return EXIT_FAILURE;
        }listener = socket(AF_INET, SOCK_STREAM, 0);
    这句的时候,产生了两个新线程下面代码接上
        /*
         * Bind our local address
         */
        memset(&serverAddress, 0, sizeof(serverAddress));
        serverAddress.sin_family      = AF_INET;
        serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
        serverAddress.sin_port        = htons(SERV_TCP_PORT);    err = bind(listener,
                (struct sockaddr *)&serverAddress,
                sizeof(serverAddress)
              );
        if (err < 0)
        {
            int i = GetLastError();
            FatalError("bind() failed");
        }
                listen(listener, 5);    fprintf(stderr, "Echo Server with I/O Completion Ports\n");
        fprintf(stderr, "Running on TCP port %d\n", SERV_TCP_PORT);
        fprintf(stderr, "\nPress Ctrl+C to stop the server\n");    //
        // Loop forever accepting requests new connections
        // and starting reading from them.
        //
        for (;;)
        {
            struct ContextKey *pKey;        clientAddressLength = sizeof(clientAddress);
            newsocket = accept(listener,
                                (struct sockaddr *)&clientAddress,
                                &clientAddressLength);
            if (newsocket < 0)
            {
                FatalError("accept() Failed");
                return EXIT_FAILURE;
            }        newsocket = accept(listener,
                                (struct sockaddr *)&clientAddress,
                                &clientAddressLength);当有第一个连接进来的时候,又产生新的两个线程。第二、三。。个不变再次申明,标准里面应该没有规定产生多少线程, 只做为windows机制的一种属性,如果有兴趣的兄弟可以稍微讨论下
      

  8.   


    比如wininet,等等,不信你自己去试试
    库起不起线程你是不应该关心的,只要他行为正确即可
      

  9.   

    菜单
    调试-》窗口-》线程我用vc2008,别的IDE不知道有没有
      

  10.   

    你说资源管理器里看到,是在调试的时候吧?
    我估计可能是IDE注入的调试线程(猜的,没根据)
      

  11.   


    我也是VS08,有产生线程。03系统。为了排除IDE的注入,在生成的EXE里直接运行(socket这个是监视不了),在accept的时候确认如同我第二点所说,您可以试试
      

  12.   

    我xpsp2,
    试了下直接运行exe,用telnet连接,从任务管理器里看始终只有1个线程
      

  13.   

    wininet属于高级库,在接口层上面进行了二次封装而已,连应用层协议都封进去了还,要这么说MFC的库还有好多了,不能混在一起理解。winapi本身基本不会做隐藏性质的活动,当然,我知道的不全。但是理解库的行为到底做了什么,才能正确使用库,并且库也是有bug的,就拿你说的inet库来讲,它设置连接超时是不生效的。简单socket模型本身,没有接口会起线程的。我还是认为线程是楼主自己起的
      

  14.   

    如果有IDE的话,可以直接看看线程的call stack,没有的话,挂windbg跑,用~*命令看下,一样,想看的东西都有
      

  15.   

    再说明下,如果是调试器注入的线程,看下call stack,应该是有sysdbg这样的类似接口调用
      

  16.   


    ...不知道你在争论些什么,你问的是库,我回答的是库,还有,我什么时候说线程是winsock起的了,你理解了我的回复再说吧。就算是winapi内部起了线程又怎么样?只要不在文档里说明,就属于实现细节,根本不是该关注的事,你要依赖这个细节,你就已经错了。
      

  17.   

    不必深究,windows本身就有一个线程池支持。在其平台下实现的套接字,特别是异步下,可能会涉及的线程池的使用。因此其实现细节不必深究,除非哥们你特别需要。