본문 바로가기

카테고리 없음

[네트웍/인터넷] Winsock WriteFile and Overlapped IO

반응형
procedure SendToSocket(Sock : TSocket; Data : PaData; Len : Integer);
var
  Overlap : OVERLAPPED;
  BytesWritten : DWord;
  BytesSend : Integer;
begin
  { create overlapped structure with controlling event }
  FillChar(OverLap, SizeOf(OVERLAPPED), 0);
  OverLap.hEvent := CreateEvent(nil, True, False, '');
  if OverLap.hEvent = 0 then
    { event is not created }
    RaiseLastWin32Error;
  try
    BytesSend := 0;
    while BytesSend < Len do begin
      if not WriteFile(Sock, Data^[BytesSend], Len - BytesSend, BytesWritten, @Overlap) then begin
        if GetLastError <> ERROR_IO_PENDING then
         { non-recoverable WriteFile error }
          RaiseLastWin32Error;
        { wait for 10 seconds for our write to complete }
        case WaitForSingleObject(Overlap.hEvent, 10000) of
        WAIT_OBJECT_0:
          if not GetOverlappedResult(Sock, OverLap, BytesWritten, False) then
            { GetOverlappedResult failed }
            RaiseLastWin32Error;
        WAIT_TIMEOUT:
          raise Exception.Create('Timed out waiting for our write to complete');
        else
          RaiseLastWin32Error;
        end;
      end;
      if BytesWritten = 0 then
        { peer must have terminated connection }
        raise Exception.Create('Connection is closed before sent has completed');
      Inc(BytesSend, BytesWritten);
    end;
  finally
    CloseHandle(Overlap.hEvent);
  end;
end;
반응형