wininet  
InternetOpen
InternetConnect
httpsendrequestex
这些操作之后
等下次 我再次向 服务器 post数据的时候
用httpsendrequestex 用抓包工具发现 httpsendrequestex 是一个单独的连接
而不像socket那样,建立连接之后,以后的send数据 都是一个连接
有大虾知道这是什么原因吗

解决方案 »

  1.   

    贴出代码
    初始化wininet
    var
      AccessType: DWORD;
      User: PWideChar;
      Pass: PWideChar;
      //info: INTERNET_PROXY_INFO;
    begin
      if FInet = nil then
      begin
      AccessType := INTERNET_OPEN_TYPE_PRECONFIG;
      FInet := InternetOpenW(nil, AccessType, nil, nil, INTERNET_FLAG_ASYNC);  // info.dwAccessType := INTERNET_OPEN_TYPE_PROXY;
      // info.lpszProxy := '192.168.1.93: 808';
      // InternetSetOption(FInet, INTERNET_OPTION_PROXY, @info, 2000);  WinInetCheck(FInet <> nil);
      FLastInternetStatusCallback := TInternetStatusCallback(
      InternetSetStatusCallback(FInet,
      @InternetStatusCallback_TWinInetHttpConnection));
      end;
      if FConnect = nil then
      begin  if FUsername = '' then
      User := nil
      else
      User := PWideChar(FUsername);
      if FPassword = '' then
      Pass := nil
      else
      Pass := PWideChar(FPassword);
      FConnect := InternetConnectW(FInet, PWideChar(FHost), FPort, User,
      Pass, INTERNET_SERVICE_HTTP, 0, DWORD(Self));
      WinInetCheck(FConnect <> nil);
      end;openrequest
    const
      ContextType = 'application/octet-stream';
    var
      Flags: DWORD;
      AcceptTypes: array[0..1] of Pointer;
      Header: WideString;  isSecure: Boolean;
      Len: DWORD;
      HeaderAdded: Boolean;
    begin
    {$IFDEF DEBUG}
      OutputDebugString('TWinInetHttpConnection.OpenRequest');
    {$ENDIF}
      if FRequest <> nil then
      begin
      Async(_FirstSendRequest);
      Exit;
      end;
      Flags := INTERNET_FLAG_KEEP_CONNECTION or INTERNET_FLAG_PRAGMA_NOCACHE or INTERNET_FLAG_NO_CACHE_WRITE;
      isSecure := WideSameText(FScheme, 'https');
      if isSecure then
      begin
      Flags := Flags or INTERNET_FLAG_SECURE;
      // if IgnoreCertCNInvalid then
      Flags := Flags or INTERNET_FLAG_IGNORE_CERT_CN_INVALID;
      // if IgnoreCertDateInvalid then
      Flags := Flags or INTERNET_FLAG_IGNORE_CERT_DATE_INVALID;
      end;  AcceptTypes[1] := nil;
      PWideChar(AcceptTypes[0]) := ContextType;
      if FRequest = nil then
      begin
      FRequest := HttpOpenRequestW(FConnect, PWideChar(FMethod), PWideChar(FPath),
      nil, nil, nil, Flags, DWORD(Self));
      if FRequest <> nil then
      begin
      Header := 'Content-Length: 2000000000' + #13#10;
      HeaderAdded:= HttpAddRequestHeadersW(FRequest, PWideChar(Header),
      Length(Header), HTTP_ADDREQ_FLAG_ADD);
      end;
      end;
      WinInetCheck(FRequest <> nil);
    end;httpsendrequestex
    const
      BufferSize = 1024;
    var
      N: Cardinal;  Buffer: array[0 .. BufferSize - 1] of Byte;  SendBuffer: TInternetBuffersW;
      Size, O, C: Cardinal;
      StrP: PAnsiChar;
      str : WideString;
      flage : Cardinal;
      b: Boolean;
      writen: DWORD;
      w : WideString;
    begin
    {$IFDEF DEBUG}
      OutputDebugString('TWinInetHttpConnection._FirstSendRequest');
    {$ENDIF}
      if (FContent = nil) or (FContent.Size = 0) then
      begin
      Next^ := _EndRequest;
      Result := HttpSendRequestExW(FRequest, nil, nil, 0, Cardinal(Self));
      Exit;
      end;  // TODO 如果流不大的话,应该可以直接上传  Size := FContent.Size;
      FillChar(SendBuffer, SizeOf(SendBuffer), 0);
      SendBuffer.dwStructSize := SizeOf(SendBuffer);
      SendBuffer.dwBufferTotal := Size;  if Size < DirectSendBufferSize then
      begin
      Next^ := _EndRequest;  O := 0;
      repeat
      C := FContent.Read(@FDirectSendBuffer[O], Size);
      if C = 0 then
      Break;
      O := O + C;
      Assert(C <= Size);
      Size := Size - C; // TODO 这里不安全,如果 C > Size 的话
      until Size = 0;  SendBuffer.lpvBuffer := @FDirectSendBuffer[0];
      SendBuffer.dwBufferLength := O;  Result := HttpSendRequestExw(FRequest, @SendBuffer, nil, 0,dword(Self));
      if not FisSendData then
      FisSendData := true;
      Exit;
      end;
      

  2.   

    结束请求
    function _EndRequest(Next, Retry: PWinInetMethod): Boolean;
    begin
    {$IFDEF DEBUG}
      OutputDebugString(_EndRequest');
    {$ENDIF}
      Result := HttpEndRequestW(FRequest, nil, 0, 0);
    end;关闭
    procedure Close;
    begin
    {$IFDEF DEBUG}
      OutputDebugString('Close');
    {$ENDIF}
      InternetCloseHandle(FRequest);
      InternetCloseHandle(FConnect);
      InternetCloseHandle(FInet);  // TODO
      Application.ProcessMessages;{$IFDEF DEBUG}
      OutputDebugString('Close');
    {$ENDIF}
    end;