cpu:i7 3632qm 2.20HGz 4核8线程
内存: 8g
操作系统:windows8工具:vs2012
服务端目的群发系统
框架用iocp tcp想实现100w tcp连接,服务器端群发通知.每个包非常小,不超过1024字节
现在在WSASocketW和send函数遇到了瓶颈,调用他们很高几率需要16毫秒.
能不能通过修改注册表或者给系统一些特殊的加速达到让WSASocketW和send 0延迟.现在测试的情况(服务端和客户端都在一台机器);
服务器最高1w/s连接,平均在7k/s左右.主要是WSASocketW占用时间比较高.(客户端发送1个登陆指令大约30字节,服务器端回复一个登陆成功指令也30字节,客户端收到算登陆成功).
群发只用了1个线程,2w次/s的发送速度,如果注释掉send函数 100w在1秒之内就运行完了.请大侠们帮帮忙iocp服务器群发

解决方案 »

  1.   

    多线程处理呗
    要不就用UDP
      

  2.   


    谢谢大哥回复
    是要做多线程,但是现在一个线程处理的太慢了.
    客户端是其他人写的,他们要求用tcp.不过按现在的问题改成udp应该也解决不了吧.
      

  3.   


    谢谢二哥...
    二哥说的是,相当于游戏的聊天服务器.
    队列系统以前做过,那时候队列处理没有iocp快,玩家收到信息会延迟.而且内存不好控制,会一直在增长.
    还有他们要求很高,管理员发送完信息,需要其他玩家5秒内收到.现在代码正在改成linux的,准备去linux下试试
      

  4.   

    还是没有解决,不过直接用了DeviceIoControl,速度快了一些,接收2.5w连接基本快1秒,而且发现关闭360会快1秒.这里的意思我也不太明白,是反汇编得到的. 等待大神们看看能不能再优化//创建socket
    static UNICODE_STRING filename = {0x28,0x2A,L"\\Device\\Afd\\Endpoint\0"};
    static OBJECT_ATTRIBUTES oa = {sizeof(OBJECT_ATTRIBUTES),0,&filename,OBJ_CASE_INSENSITIVE|OBJ_INHERIT};
    static _CREATE_SOCKET cs = {0,0x1e0f00,"AfdOpenPacketXX",0x00,AF_INET,SOCK_STREAM,IPPROTO_TCP,0,PFL_MATCHES_PROTOCOL_ZERO,0,0x01};
    static _AFD_SET_INFO si = {0x00,AF_INET,SOCK_STREAM,IPPROTO_TCP,
    sizeof(sockaddr_in),sizeof(sockaddr_in),0x00,0x00,
    0x00,0x010000,0x010000,0x1000,
    0x01,0x03E9,
    XP1_IFS_HANDLES|XP1_EXPEDITED_DATA|XP1_GRACEFUL_CLOSE|XP1_GUARANTEED_ORDER|XP1_GUARANTEED_DELIVERY,
    PFL_MATCHES_PROTOCOL_ZERO,
    0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,
    0x00,0x00,WSAID_TCP_IP,0x04,0x00,
    0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,
    0x02
    };IO_STATUS_BLOCK isb;
    //WSASocket的FILE_NON_DIRECTORY_FILE|FILE_SEQUENTIAL_ONLY|FILE_NO_INTERMEDIATE_BUFFERING是0,我加上这个速度稍微会快些但不知道会不会出问题
    NtCreateFile((PHANDLE)&m_Socket,GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE|WRITE_DAC,&oa,&isb,0,0,FILE_SHARE_READ|FILE_SHARE_WRITE,FILE_OPEN_IF,FILE_NON_DIRECTORY_FILE|FILE_SEQUENTIAL_ONLY|FILE_NO_INTERMEDIATE_BUFFERING,&cs,sizeof(cs));
    NtDeviceIoControlFile((HANDLE)m_Socket,0,0,0,&isb,IOCTL_AFD_SET_CONTEXT,&si,sizeof(si),0,0);//发送函数send
    _AFD_SEND_INFO SendInfo;
    _AFD_WSABUF buffer;
    IO_STATUS_BLOCK dwFlag;
    dwFlag.Status = 0x103;buffer.buf = (char*)buf;
    buffer.len = len;SendInfo.BufferArray = &buffer;
    SendInfo.BufferCount = 1;
    SendInfo.AfdFlags = 0;
    SendInfo.TdiFlags = 0;//接收TCP
    //DeviceIoControl()
    //send(m_Socket,buf,len,0);

    if(NtDeviceIoControlFile((HANDLE)m_Socket,NULL,0,0, &dwFlag,IOCTL_AFD_SEND,&SendInfo,sizeof(SendInfo),0,0)==STATUS_SUCCESS)
    {
    ret = dwFlag.Information;
    }//acceptex
    m_OverlappedPlus.Internal = 0x103;
    _AFD_ACCEPT_INFO acceptInfo = {0,m_AcceptItem->GetSocket(),0,0x20,0x20};int ret = NtDeviceIoControlFile((HANDLE)m_Socket,0,0,&m_OverlappedPlus,(PIO_STATUS_BLOCK)&m_OverlappedPlus,IOCTL_AFD_ACCEPT_EX,&acceptInfo,sizeof(acceptInfo),m_Buffer,0x40);
      

  5.   

    你应该明白,系统完成send操作是需要时间的,如果网络状态不好,数据发送慢,send缓冲区满意了,你的send还会被阻塞掉。你这需求跟要求一秒钟到达火星一样。不管你用多线程、非阻塞还是IOCP,操作系统完成你的操作都需要时间,16ms是一个很正常的时间。