打印本文 打印本文 关闭窗口 关闭窗口
Winsock完成端口模型-Delphi代码
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1862  更新时间:2009/4/23 18:27:12  文章录入:mintao  责任编辑:mintao
;
begin
   CompletionPort := THANDLE( CompletionPortID);

   Result:= 0;

   while(TRUE) do
   begin

      if (GetQueuedCompletionStatus(CompletionPort, BytesTransferred,
         DWORD(PerHandleData), POverlapped(PerIoData), INFINITE) = False) then
      begin
         printf(''''GetQueuedCompletionStatus failed with error %d'''', GetLastError());
         exit;
      end;

      // First check to see if an error has occured on the socket and if so
      // then close the socket and cleanup the SOCKET_INFORMATION structure
      // associated with the socket.

      if (BytesTransferred = 0) then
      begin
         printf(''''Closing socket %d\'''', PerHandleData.Socket);

         if (closesocket(PerHandleData.Socket) = SOCKET_ERROR) then
         begin
            printf(''''closesocket() failed with error %d'''', WSAGetLastError());
            exit;
         end;

         GlobalFree(DWORD(PerHandleData));
         GlobalFree(DWORD(PerIoData));
         continue;
      end;

      // Check to see if the BytesRECV field equals zero. If this is so, then
      // this means a WSARecv call just completed so update the BytesRECV field
      // with the BytesTransferred value from the completed WSARecv() call.

      if (PerIoData.BytesRECV = 0) then
      begin
         PerIoData.BytesRECV := BytesTransferred;
         PerIoData.BytesSEND := 0;
      end
      else
      begin
         PerIoData.BytesSEND := PerIoData.BytesSEND + BytesTransferred;
      end;

      if (PerIoData.BytesRECV > PerIoData.BytesSEND) then
      begin

         // Post another WSASend() request.
         // Since WSASend() is not gauranteed to send all of the bytes requested,
         // continue posting WSASend() calls until all received bytes are sent.

         ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));

         PerIoData.DataBuf.buf := PerIoData.Buffer + PerIoData.BytesSEND;
         PerIoData.DataBuf.len := PerIoData.BytesRECV - PerIoData.BytesSEND;

         if (WSASend(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @SendBytes, 0,
            @(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
         begin
            if (WSAGetLastError() <> ERROR_IO_PENDING) then
            begin
               printf(''''WSASend() failed with error %d'''', WSAGetLastError());
               Exit;
            end;
         end;
      end
      else
      begin
         PerIoData.BytesRECV := 0;

         // Now that there are no more bytes to send post another WSARecv() request.

         Flags := 0;
         ZeroMemory(@(PerIoData.Overlapped), sizeof(OVERLAPPED));

         PerIoData.DataBuf.len := DATA_BUFSIZE;
         PerIoData.DataBuf.buf := @PerIoData.Buffer;

         if (WSARecv(PerHandleData.Socket, @(PerIoData.DataBuf), 1, @RecvBytes, @Flags,
            @(PerIoData.Overlapped), nil) = SOCKET_ERROR) then
         begin
            if (WSAGetLastError() <> ERROR_IO_PENDING) then
            begin
               printf(''''WSARecv() failed with error %d'''', WSAGetLastError());
               exit;
            end;
         end;
      end;
   end;
end;


end.

上一页  [1] [2] 

打印本文 打印本文 关闭窗口 关闭窗口