最近使用delphi编写iocp服务器,使用线程池和socket池,在使用AcceptEx函数时,用WSAIoctl加载时,出现了不顺利,有做过的请指教一下。谢谢!最好能亮出代码,不甚感激!delphi winsock2 AcceptExWSAIoctldelphiwinsock2

解决方案 »

  1.   

    这有很多socket源码,服务器端调用的是accept,你找一个看一下:
    http://download.csdn.net/detail/geoff08zhang/4571358  
      

  2.   

    情况是这样的:我用WSAIoctl 加载了AcceptEx函数到内存。我是这样定义的guid:
    WSAID_ACCEPTEX:TGUID = (D1: $B5367DF1; D2: $CBAC; D3: $11CF; D4: ($95, $CA, $00, $80, $5F, $48, $A1,$92));
    调用wsaioctl,成功。然后,用10 socket 发送了10个AcceptEx,方法去接受新连接。并把10个socket绑定到了完成端口上(用BindIoCompletionCallback绑定的)。也成功了。可是我在客户端连接服务端,并发送数据。服务端没有任何反应。
      

  3.   

    所以,我猜测是不是我加载的AcceptEx函数的地址不对,我调用的是不是
    acceptEx方法。我无从求证。下边把代码粘贴出来,大家看看:
      

  4.   

    Log('服务器正在启动...',[]);
      //创建socket
      FListenSock := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
      if FListenSock = INVALID_SOCKET then
      begin
        ErrorLog('创建套接字错误:%d', [WSAGetLastError]);
        exit;
      end;
      //设定地址和端口
      ListenAddr.sin_family := AF_INET;
      ListenAddr.sin_port := htons(FLocalPort);
      if FLocalAddr = '' then
        ListenAddr.sin_addr.S_addr := INADDR_ANY
      else
        ListenAddr.sin_addr.S_addr := inet_addr(pAnsichar(FLocalAddr));//一定要转化成pcahr
      //绑定
      if Bind(FListenSock, TSockAddr(ListenAddr),sizeof(ListenAddr)) <> 0 then
      begin
        ErrorLog('绑定套接字错误:%d', [WSAGetLastError]);
        //closeSocket(FListenSocket);
        exit;
      end;
      //监听
      if listen(FListenSock, SOMAXCONN) <> 0 then
      begin
        ErrorLog('监听套接字错误:%d', [WSAGetLastError]);
        //closeSocket(FListenSocket);
        exit;
      end;  Log('创建连接池....',[]);
      
      //初始化socket池锁和等待接受socket数量
      FSockListLock := TCriticalSection.Create;
      FAcceptSockCount := 0;  //加载sock2 Ex方法到内存
      FAcceptEx := nil;
      FDisconnectEx := nil;
      //LoadExFunc(FListenSock,efAcceptEx,@@FAcceptEx);
      //LoadExFunc(FListenSock,efDisconnectEx,@@FDisconnectEx);  FSockList := TList.Create;
      //发出1000个接受socket
      for i := 1 to 10 do
      begin
        //生成socket
        AccSock := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
        if AccSock = INVALID_SOCKET then
        begin
          ErrorLog('创建连接池错误:%d', [WSAGetLastError]);
          //closeSocket(FListenSocket);
          //closeAllExitsSocket
          exit;
        end;
        
        //创建overlapped数据结构
        new(olData);
        olData^.Statu := cbaAccept;
        olData^.wsaBuffer.buf := olData^.Buffer;
        olData^.wsaBuffer.len := BUFFER_SIZE;
        
        //把socket绑定到完成端口
        rt := BindIoCompletionCallback(AccSock,@DealAction,0);    //发送异步接受请求
        if FAcceptEx(FListenSock,AccSock,olData^.wsaBuffer.buf,256,256,256,
          @dwBytes,Poverlapped(olData)) then
        begin
          closesocket(Accsock);
        end;
        
        //维护sock列表和接受新链接的sock数量
        FSockList.Add(@AccSock);
        inc(FacceptSockCount);
      

  5.   

      我发一个关于扩展函数给你吧! 你留个邮箱! 我使用这个扩展库以成功使用。测试ECHO开12000个客户端没有任何问题! 不过我的异步投递是使用专门的看守线程做的! 像这样的东西还是自己调试吧! 
      

  6.   

    [email protected] 发我这个邮箱吧,谢谢!
      

  7.   

    这是我的加载winsock2 函数的方法,上次要发过3帖了,没发成。
    function LoadExFunc(sk:TSocket;fuc:TExFunc;pfun:Pointer):string;
    var
      dwBytes:DWORD;
    begin
      result := 'OK';
      dwBytes := 0;
      if sk = INVALID_SOCKET then
      begin
        sk := WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, nil, 0, WSA_FLAG_OVERLAPPED);
        if sk=INVALID_SOCKET then
        begin
          result := format('加载扩展函数时创建套接字失败,错误号:%d',[WSAGetLastError]);
          exit;
        end;
      end;
      case fuc of
        efAcceptEx:
          begin
             if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER,
               @WSAID_ACCEPTEX,sizeof(WSAID_ACCEPTEX),pfun,sizeof(pfun),dwBytes,nil,nil) then
              begin
                result := format('加载扩展函数AcceptEx失败,错误号:%d',[WSAGetLastError]);
                exit;
              end;
          end;
        efDisconnectEx:
          begin
            if SOCKET_ERROR = WSAIoctl(sk,SIO_GET_EXTENSION_FUNCTION_POINTER,
               @WSAID_DISCONNECTEX,sizeof(WSAID_DISCONNECTEX),@pfun,sizeof(pfun),dwBytes,nil,nil) then
              begin
                result := format('加载扩展函数DisconnectEx失败,错误号:%d',[WSAGetLastError]);
                exit;
              end;
          end;
      end;
    end;
      

  8.   

    无法发送到163.com
        系统应答:(13)ESO_LOCAL_SPAM: spamed by local spam engine
        退信原因:邮件被反垃圾系统认定为垃圾邮件,无法继续发送。
        解决建议:请检查邮件内容是否存在垃圾信息然后重试。居然被退回来!