如何使用Wininet将二进制(.zip)文件发送到服务器

时间:2018-07-15 10:50:01

标签: c file winapi send wininet

我想使用POST方法将文件传输到站点 在php站点上,脚本接受“ userfile”并将其保存在服务器上

data want(keep=date G NG Pd);
  if 0 then set have; * prep pdv for hash;

  * ids is the 'tracker';
  declare hash ids(); 
  ids.defineKey('id');
  ids.defineData('id', 'lastinv');
  ids.defineDone();

  lastinv = inv; * prep lastinv in pdv;

  do until (end);
    do until (last.date);

      set have end=end;
      where inv in ('Pd' 'G' 'NG');
      by date;

      if ids.find() = 0 then do; * decrement count based on ids prior inv;
        select (lastinv);
          when ('G')  G  + -1;
          when ('NG') NG + -1;
          when ('Pd') Pd + -1;
          otherwise ;
        end;    
      end;

      * update ids prior inv;

      lastinv = inv;
      ids.replace();

      * increment count based on ids prior inv;

      select (lastinv);
        when ('G')  G  + 1;
        when ('NG') NG + 1;
        when ('Pd') Pd + 1;
        otherwise ;
      end;

    end;
    OUTPUT;  * <------------ output one row of counts per date;
  end;
run;

文件未发送(请求不正确) 我可以解决吗?

UPD: 该代码是正确的。 但是我不知道如何将二进制文件放入字符数组。 这用于发送文本文件:

void SendFile()
{
  const char hdrs[] = "Content-Type: multipart/form-data; boundary=--------071418204214402\n"
  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";

  char* data1 = "----------071418204214402\n"
  "Content-Disposition: form-data; name=\"userfile\"; filename=\"file.zip\"\n"
  "Content-Type: text/plain\n"
  "Content-Transfer-Encoding: binary\n\n";

  char* filecontent = "Hello World!";       // Simulated the contents of the file with a string.

  char* data2 = "\n----------071418204214402--\n";

  char* allstr = calloc(strlen(data1) + strlen(filecontent) + strlen(data2) + 1, 1);
  strcat(allstr, data1);
  strcat(allstr, filecontent);
  strcat(allstr, data2); 

  HINTERNET hSession = InternetOpen("MyAgent", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
  HINTERNET hConnect = InternetConnect(hSession, "crazra94.beget.tech", INTERNET_DEFAULT_HTTP_PORT, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 1);
  HINTERNET hRequest = HttpOpenRequest(hConnect, "POST", "/send.php", NULL, NULL, NULL, 0, 1);

  HttpAddRequestHeaders(hRequest, hdrs, -1, HTTP_ADDREQ_FLAG_REPLACE | HTTP_ADDREQ_FLAG_ADD);
  INTERNET_BUFFERS bufferIn;
  LPDWORD bytesWritten;
  memset(&bufferIn, 0, sizeof(INTERNET_BUFFERS));
  bufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);
  bufferIn.dwBufferTotal = strlen(data1) + strlen(filecontent) + strlen(data2)+1;
  HttpSendRequestEx(hRequest, &bufferIn, NULL, HSR_INITIATE, 0);
  InternetWriteFile(hRequest, (const void*)data1, strlen(data1)+1, bytesWritten);
  InternetWriteFile(hRequest, (const void*)filecontent, strlen(filecontent)+1, bytesWritten); // File
  InternetWriteFile(hRequest, (const void*)data2, strlen(data2)+1, bytesWritten);
  HttpEndRequest(hRequest, NULL, HSR_INITIATE, 0);
}

{

void SendFile()

}

1 个答案:

答案 0 :(得分:3)

除了代码完全遗漏任何错误外,我检查以下问题:

  1. 每次对InternetWriteFile()的调用都会传递未初始化的指针作为最后一个参数。这样做会引起未定义的行为。从那时起一切都会发生。

    要解决此更改

    LPDWORD bytesWritten;
    

    成为

    DWORD bytesWritten;
    

    并像这样将其地址传递到InternetWriteFile()

    InternetWriteFile(..., &bytesWritten);
    
  2. 告诉
  3. InternetWriteFile()通过执行char来编写'\0'数组的strlen(data1)+1终止符。

    为什么?这根本不符合逻辑。 0不是文件的一部分,而只是标记字符串结尾的C伪像。

  4. HTTP标准要求文本行必须以 结尾。该代码仅使用\n)。

    将其更改为\r\n

  5. 这不是致命的,但是这样的铸件没用

    InternetWriteFile(..., (const void*)data1, ...
    

    C(相对于C ++)隐式将从/向void指针转换。所以只需使用

    InternetWriteFile(..., data1, ...