我在一个套接字(tcp,udp类型的都有)上循环发送大量数据,因为是大量数据循环发送,且每次发送前不能有延迟,所以为了防止缓冲区溢出,我想每次在发送数据前查询一下该套接字的系统缓冲池中是否还有数据待发,如果有,我就丢弃要发的数据(不是系统缓冲池中待发的数据)。不知有什么办法知道系统缓冲池中是否还有数据待发?

解决方案 »

  1.   

    用CAsyncSocket的OnSend方法,它告诉你现在可以发送数据了。
      

  2.   

    在recv中使用MSG_PEEK标志,或者调用ioctlsocket(设置FIONREAD选项),从而在系统缓冲区中,事先查看是否存在必要的字节数量。windows网络编程第二版第五章。。
      

  3.   

    to xiaohyy(醉大饿极) :
    这个选项只是在recv的时候有效,在send的时候有效吗?
      

  4.   

    我记得有啊,好像有个FD_WRITE就是判断有没有数据待发的,FD_READ是检查有没有可以读入的数据。
    你查一下具体访问它们的函数吧,我记不太清了。
      

  5.   

    vagabondkq(birder)说的是select模型,用这种模型也应该可以吧。。
      

  6.   

    我是想在新一轮发送数据前检查一下缓冲池中的以前的数据发送完了没有,如果发送完了我就继续发送这一轮的数据,否则就丢弃这一轮的数据。我的目的只是想查询缓冲池,就像调用ioctlsocket(设置FIONREAD选项)一样,在读数据之前可以查看缓冲池中有多少个字节的数据可以读。而FD_WRITE和FD_READ都只是触发一个事件。
      

  7.   

    如果是用TCP/IP的阻塞方式,不用去查询。服务器未发完是不能关闭的。
      

  8.   

    >>如果发送数据太快的话,缓冲池溢出的话,会出现什么样的结果?被溢出的数据被丢弃?还是会出现异常,导致该套接字自动关闭?丢弃
      

  9.   

    不知道!用select模型?还是……
    你自己判断一下?不过这样的效率太低了!那位有更好的办法?
      

  10.   

    tcp缓冲不够的时候不会继续发的.
    不够TCP下的这个概念我现在也不太清楚.
    一个是窗口大小.
    一个是套接字缓冲区大小.
    还有一个是MSS大小,这三个大小各有什么用处,哪位能讲讲吗?
    我看了LINUX原代码里面好像都是取决于网络的MSS大小,其他的都用处不大.
      

  11.   

    select()不就可以判断缓冲区里是否有数据待发或接收到数据么?
    感觉就是你想要的功能。没有你想象那么麻烦的。
      

  12.   

    FD_ZERO(&m_detected);
    FD_SET(pConnecct->conSocket,&m_detected); if(select(0,NULL,&m_detected,NULL,NULL) == SOCKET_ERROR )
    {
    UINT ret = WSAGetLastError();
    if(WSAENETDOWN == ret)
    pConnecct->tickcount++;
    if(WSAENOTSOCK == ret)
    pConnecct->tickcount++;
    }else
    {
    pConnecct->tickcount = 0;
    }
      

  13.   

    fd_set readfds;
    FD_ZERO(&readfds);
    FD_SET(sock,&readfds);
    timeout.tv_sec=5; //5s
    timeout.tv_usec=0;
    select(0,&readfds,0,0,&timeout);
      

  14.   

    select可以帮你决定,只要你把该套接字加入到fd_write集合中即可.
      

  15.   

    to sevencat(七猫):
    这三个问题的个人理解:套接字缓冲区大小和窗口大小:操作系统底层实际上给每个套接字分配了一个默认大小的缓冲区。发送数据时,send()函数会立即返回,但并不表示数据已经传到网络上,而只是已经放到了缓冲区了。缓冲区中的数据什么时候发送是由对方的窗口大小决定的。而对方的窗口大小被放在对方回应你的数据中。如果对方的窗口大小大于0,则缓冲区中的数据就会被自动发送出去。
    而窗口大小是由什么决定的呢?是由接受数据的那个套接字的缓冲区决定的,如果缓冲区没有满的话,就把窗口大小置大于0,否则小于0。
    网络的MSS大小:我觉得这是由网络设备,如路由器,交换机和网络环境决定的,他决定了你发送的数据是否要分片,每片被分成多大。如果你的数据大于网络的MSS,则要分片,否则按原包发送。个人见解,仅供参考.
      

  16.   

    to xiaohyy(醉大饿极):你确定是被丢弃?还有,如果缓冲池中还有1k的空间,而我现在要发的数据是2.5k,那么被丢弃的是1.5k还是2.5k???这个问题很关键!
    如果是udp的话,而2.5k的数据是一个完整的数据包的话,他会丢掉整个数据包.但是对于tcp,因为是数据流,我不知道丢掉的是2.5k还是会先填满缓冲池,而只丢掉1.5k
      

  17.   

    谢谢大家,我已经搞定了。对于阻塞套接字,如果缓冲池溢出了,再发送的话,就会一直阻塞在那里。对于非阻塞套接字,如果缓冲池溢出了,则send()函数返回WSAEWOULDBLOCK.不过还是没有办法知道缓冲区中还有多少数据。
      

  18.   

    #define SO_MAX_MSG_SIZE 0x2003,即8195,比8K稍多一些。