创建套接字相对来说比较耗时.

解决方案 »

  1.   

    shutdown可以吗?我想对一个套接字进行 memzero 操作,达到他刚刚被创建时的状态.
      

  2.   


    一个连接就要用一个套接字来维持啊,
    connect时会生成这个套接字,而原来的套接字还在监听,
    你要使用这个新的套接字来通讯,完了删掉就行了
      

  3.   

    listen(socket1)  //一直监听
    while(true)
    {
    socket2=accept()  //得到连接上的client socket
    }
      

  4.   

    你们在说什么啊.SOCKET hSocket=INVALID_SOCKET;hSocket=WSASOCKET(...);if (hSocket==INVALID_SOCKET)
    { return;}iRet=connect(hSocket,.....)if(iRet==SOCKET_ERROR)
    { return;}//到这个地方hSocket已经连接成功了, 可是我想断掉他,让他再做别的事情,就象一个CDatabase
    // 可以连接到一个数据库,然后close,然后再连接导另外一个数据库
    // 我不想closesocket,再wsasocket(...)一个新的。我想重新利用。.....(对socket的一些操作?????应该做什么操作)bind(hSocket....); //如果没有操作,这儿肯定会出错的。我试过几种方法,都不行。像shutdown,wsasenddisconnect, 指定了断开连接的tranmitfile。都不行listen(hSocket,..);
      

  5.   

    一样的,你close,再create就可以了
      

  6.   

    to zhangyiabc
    closesocket,就相当于delete 释放资源了,能不能不释放资源只初始化?to iicup(双杯献酒)我不是想又监听又连接,我是想连接完毕后,再把它初始化,然后再去监听.
      

  7.   

    我的真正目的我想把一个已经建立好的连接关闭,我呢,还不想closesocket,而是把相应的socket放入一个链表中,
    等待有新的套接字的需求的时候,就从链表中取出一个socket,去使用.
    进行的操作,可能是connect(hSocket,...) 也可能是lpfnAcceptEx(hSocket,....)
    ,也可能是绑定一个另外的端口.http://community.csdn.net/Expert/topic/3657/3657040.xml?temp=.7058069
      

  8.   

    楼主的意思应该是Accept后的套接字能不能继续Listen
    其实Accept后产生了一个新的套接字,与Accept的连接关联
    原Listen的套接字继续Listen
    所以不用重新创建套接字,绑定
    原侦听中的套接字依然继续侦听
    服务器都是这样实现的
      

  9.   

    如果大家都不了解你的意思,受不了的应该是你自己的表达能力:-)如果照你说的,其实只是将句柄变量放到队列中
    与是否closesocket无关
    closesocket后照样socket变量照样可以存在于队列中
    下次Accept或Connect得到的socket存于在队列中的socket变量就好但是不关闭socket,会消耗系统资源.
      

  10.   

    我们限定于一个web服务器的开发吧一个连接连上来,服务端会acceptEx,(注意:accept返回一个新的套接字,而acceptex需要你传一个全新的套接字进去,等accpetex函数返回,这个全新的套接字已经是可以跟客户端收发数据了).BOOL AcceptEx ( 
      SOCKET sListenSocket,      
      SOCKET sAcceptSocket,      
      PVOID lpOutputBuffer,      
      DWORD dwReceiveDataLength,  
      DWORD dwLocalAddressLength,  
      DWORD dwRemoteAddressLength,  
      LPDWORD lpdwBytesReceived,  
      LPOVERLAPPED lpOverlapped  
    );我想需要的就是传给acceptex的sAcceptSocket,不是每次都用wsasocket(...)建立的.
    而是,所有的可用套接字都存在一个链表中.acceptex之前,就从链表中取一个.上面说的 当然谁都会了,有不会的吗?最重要的问题在这儿,当web服务器与客户端的连接断了之后,这个sAcceptSocket怎么办????方法1: closeSocket? 这个任何人都会.方法2:  初始化到刚创建的状态,放入可用队列中,等待下次客户端连上来时再用怎么初始化????????????????????????????????????????????????????????????????????????????
      

  11.   

    to swordman:哪儿有错误啊,您给讲讲,我可能太乱了
      

  12.   

    监听是单独得一个socket,只负责做做让另外一个socket,accept,继续做事情
      

  13.   

    为什么没有明白的。to flinming:那accppt之后,recv write 之后,不需要这个套介子了,是不是改closesocket她了。
    可是我不想closesocket她,我想留下来为以后备用,就不用再wsasocket(..)了可是经过什么处理,才能让这个陶介子达到最初的刚被创建的状态,这样我才能再用到别的地方阿?
      

  14.   

    to wd_6532(无心):
      做一个真正程序员,我们更应该关心我们的应用效率。如果你真的很关心你的程序的效率和操作系统的核心效率,我建议多看看操作系统的核心技术,不管是Windows还是Unix、Linux、VXWorks、Nucleus等等,都有相关的资料介绍,Linux的源码很容易得到,/usr/src/里面有的是,kernel,net下面包含了大部分的网络代码,现在流行的Web服务aparche的源码网上有的是。就TCP/IP应用来说你可以参考一下TCP/IP详解卷一:协议,卷二:实现(有源码分析),卷三:TCP事务以及(各种)应用。等你真正熟习了它的原理,你就会对你的问题得到答案,回头也就不会再提出类似的问题了。也就是说,现在有很多人都明白了你“从头到尾”的意思,但没有人能够对你的需求提出解决方案。
      

  15.   

    现在有很多人都明白了你“从头到尾”的意思,但没有人能够对你的需求提出解决方案。这句话就更不明白了。是我的问题用语言没有办法说。我记得csdn上很多人都是能够开发或者看过web server的源代码的,对于频繁的陶介子的使用
    是怎么出出里的,假如一秒钟有5000个访问者,那程序就要创建5000的陶介子,还要销毁5000个套介子。
    怎么我一问,就没有人回答了。
      

  16.   

    对于Web服务的TCP连接来说,一般都是由客户端主动连接,而当服务器完成数据的传输后,采用主动关闭方式,就套接子来说,必须调用clost来还给核心调用,如果大量使用socket又没有交换给系统,核心会为过多的socket资源而严重降低。核心系统调配资源来处理套接子,并非如你开始所述:“创建套接字相对来说比较耗时”,核心的效率一般比我们开发的用户态程序效率高很多很多。所以,你完全没必要来保存你的套接子,核心系统处理socket的链表的效率和安全考虑比我们自己的实现也高得多!(看看源码,你就会很惊讶:核心的开发者不愧为高人!)
    当你采用accept响应客户的请求时,它一定会给你一个由核心TCP/IP处理完连接后的socket(你无法干预),如果你不接收这个套接子,那么它就被你丢失在你的进程中,直到你的进程消失,核心才有机会将该丢失的套接子资源收回。除非你避开socket的API调用而自己来实现TCP连接的代码实现。
    至于你所说的:假如一秒钟有5000个访问者,那程序就要创建5000的陶介子,还要销毁5000个套介子。
    不错。当你浏览网站时,经常会遇到“服务器忙,无法连接”,往往就是访问的客户太多而暂时无法再给你提高访问。
      

  17.   

    to wd_6532(无心) 懂你意思偶也想这样做 好像是有办法的 我在尝试中...
      

  18.   

    to ljhnew: 我要的就是你这句话,只要有个高人说,用完之后必须closesocket,而不用暂存,那我就不存了. 我就不停的创建,关闭,你的意思是说,核心有一层套接字缓冲池的东西是吧.另外:
     我接受客户端的请求时,可以不用accept函数,而是用acceptex,这样就可以自己控制通信套接字的创建了to  click2004:
     如果系统没有缓冲池的话,肯定有程序实现的,你再找找,我英语不好,国外站点肯定有解决方案.
      

  19.   

    ljhnew说的没有错。
    楼主你的出发点本来是很好,不过这样做好象行不通,就象你用CreateFile创建了一个文件句柄,下次还想用这个句柄去打开另一个文件,道理是一样的。SOCKET象句柄一样只是一个值,一个指向某个内核对象的资源符号而已。
      

  20.   

    我想这个做法也不是绝对的不行,但是是操作系统在做,也没听说过windows有提供这种方法。
      

  21.   

    这种缓存也不必要到TCP连接这个层面上来做的,因为系统资源毕竟有限,可以到应用层来做啊,就如同人家做负载平衡一样。
      

  22.   

    我个人的看法是不可以,因为如果搂主说的的确是TCP套接字的话,那么在TCP得Connect 过程中,两端的套接字会进行相关的握手操作在这个过程中他们会协商很多信息,这些信息是两个特定套接字相互识别的信息,记得在哪本书中看过,TCP的实现中要具有如下特性,能够保证在一定时间内的突然断开后还能继续通讯(好像是5分钟),因此这就需要两端都能够在异常"断开"后还能够继续识别对方。个人看法,不知道对不对
      

  23.   

    针对AcceptEx function [Winsock],我们一般不提倡使用,它是Windows独有的,并不是socket的标准调用,微软在它的MSDN中确实说过,在WIN32中使用AcceptEx 要比accept 相对要快,但在每次该使用它之前,必须调用GetAcceptExSockaddrs来做初始化工作(包括data, local socket address, and remote socket address),调用需要Windows Sockets 2支持,使用起来相当麻烦,尤其是在管理大量使用socket时,你不得不走很多弯路,其效率未必就比标准调用高。如果你真的坚持要用这些,等到做了很多工作后,说不定回头你会发现还不如一开始就用标准的系统调用,特别是兼容POSIX标准,当开发到一定程度,在考虑到程序移植工作时,就更显显出标准使用的必要性。AcceptEx 详细请参考:
    ms-help://MS.MSDNQTR.2004OCT.1033/winsock/winsock/acceptex_2.htm
    Requirements系统需求
    Client: Requires Windows XP, Windows 2000 Professional, or Windows NT Workstation 3.51 and later.
    Server: Requires Windows Server 2003, Windows 2000 Server, or Windows NT Server 3.51 and later.
    Header: Declared in Mswsock.h.
    Library: Use Mswsock.lib.
    See Also
      

  24.   

    哎呀,看迷糊了。总之一句话,端口既然已经分发出去了,想复用就要close掉后再用,否则是绝对不行的。
    也就是说,你也改变一个端口的连接行为,就必须把那个端口弄回到初始状态,否则对它的一切操作都是非法的。
      

  25.   

    AcceptEx 的目的不是干这个用的。楼主使用API之前,应该先理解提供这个API的思想。
      

  26.   

    我的理解是:
     
    accetpex的目的是
    1 非阻塞
    2 在客户端没有连接进来之前创建好通信套接字,并把它放入接受请求包中投递出去.
    3 同时投递1000个acceptex,可以同时接受1000个连接.
      否则,假如系统能预先接纳50个,只能处理完50个,再处理下50个.这就要在客户端等待的时候创建会话资源.
      

  27.   

    to fisker0303:
     linux的close,win的closesocket 之后,资源已经释放了,不能再用了.
      

  28.   

    楼主的意思是要用socket连接池吧?规定最多同时有N个连接,这些连接可以复用?
      

  29.   

    AcceptEx 怎么是非阻塞呢?windows使用AcceptEx 是采用overlapped IO的模式,并且使用是往往使用Windows events 或 completion ports 来实现。如果你一定要使用,给你一个例子好好分析吧。The following example uses the AcceptEx function using overlapped I/O and completion ports.#include <stdio.h>
    #include "winsock2.h"
    #include "mswsock.h"void main() {
      //----------------------------------------
      // Declare and initialize variables
      WSADATA wsaData;
      HANDLE hCompPort;
      LPFN_ACCEPTEX lpfnAcceptEx = NULL;
      GUID GuidAcceptEx = WSAID_ACCEPTEX;
      WSAOVERLAPPED olOverlap;
      
      SOCKET ListenSocket, AcceptSocket;
      sockaddr_in service;
      char lpOutputBuf[1024];
      int outBufLen = 1024;
      DWORD dwBytes;  //----------------------------------------
      // Initialize Winsock
      int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
      if( iResult != NO_ERROR )
        printf("Error at WSAStartup\n");  //----------------------------------------
      // Create a handle for the completion port
      hCompPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, (u_long)0, 0 );  //----------------------------------------
      // Create a listening socket
      ListenSocket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
      if (ListenSocket == INVALID_SOCKET) {
        printf("Error at socket(): ListenSocket\n");
        WSACleanup();
        return;
      }  //----------------------------------------
      // Associate the listening socket with the completion port
      CreateIoCompletionPort((HANDLE)ListenSocket, hCompPort, (u_long)0, 0);  //----------------------------------------
      // Bind the listening socket to the local IP address
      // and port 27015
      hostent* thisHost;
      char* ip;
      u_short port;
      port = 27015;
      thisHost = gethostbyname("");
      ip = inet_ntoa (*(struct in_addr *)*thisHost->h_addr_list);  service.sin_family = AF_INET;
      service.sin_addr.s_addr = inet_addr(ip);  service.sin_port = htons(port);  if ( bind( ListenSocket,(SOCKADDR*) &service, sizeof(service) )  == SOCKET_ERROR ) {
        printf("bind failed\n");
        closesocket(ListenSocket);
        return;
      }  //----------------------------------------
      // Start listening on the listening socket
      if (listen( ListenSocket, 100 ) == SOCKET_ERROR) {
        printf("error listening\n");
      } 
      printf("Listening on address: %s:%d\n", ip, port);  //----------------------------------------
      // Load the AcceptEx function into memory using WSAIoctl.
      // The WSAIoctl function is an extension of the ioctlsocket()
      // function that can use overlapped I/O. The function's 3rd
      // through 6th parameters are input and output buffers where
      // we pass the pointer to our AcceptEx function. This is used
      // so that we can call the AcceptEx function directly, rather
      // than refer to the Mswsock.lib library.
      WSAIoctl(ListenSocket, 
        SIO_GET_EXTENSION_FUNCTION_POINTER, 
        &GuidAcceptEx, 
        sizeof(GuidAcceptEx),
        &lpfnAcceptEx, 
        sizeof(lpfnAcceptEx), 
        &dwBytes, 
        NULL, 
        NULL);  //----------------------------------------
      // Create an accepting socket
      AcceptSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
      if (AcceptSocket == INVALID_SOCKET) {
        printf("Error creating accept socket.\n");
        WSACleanup();
        return;
      }  //----------------------------------------
      // Empty our overlapped structure and accept connections.
      memset(&olOverlap, 0, sizeof(olOverlap));  lpfnAcceptEx(ListenSocket, 
        AcceptSocket,
        lpOutputBuf, 
        outBufLen - ((sizeof(sockaddr_in) + 16) * 2),
        sizeof(sockaddr_in) + 16, 
        sizeof(sockaddr_in) + 16, 
        &dwBytes, 
        &olOverlap);  //----------------------------------------
      // Associate the accept socket with the completion port
      CreateIoCompletionPort((HANDLE)AcceptSocket, hCompPort, (u_long)0, 0);  //----------------------------------------
      // Continue on to use send, recv, TransmitFile(), etc.,.
      ...}
      

  30.   

    to allenq:差不多吧,不过我想复用的不是已经建立好的socket连接,而是socket套接字资源(我为什么要加资源两个字吗,因为如果我说套接字,就又会有人站出来说,我其实是一个数字)
      

  31.   

    to ljhnew:
     acceptex不是非阻塞的难道是阻塞的吗?虽然他不是真正的接受一个连接请求,
    但是相对与阻塞的accept和阻塞的wsaaccpet来说,accpetex不是绝对是非阻塞函数吗?
      

  32.   

    一般服务器有两个主要的socket,首先创建一个线程负责Listen,得到一个连接后重开一个线程负责该连接。