wininetでPOSTで値を渡せません

このQ&Aのポイント
  • wininetを使ってPOST形式でサーバにパラメータを渡す方法がわかりません。
  • HttpOpenRequestかHttpSendRequestに問題があると思いますが、解決策がわかりません。
  • 環境はvc++2005です。
回答を見る
  • ベストアンサー

wininetでPOSTで値を渡せません

winnetを使ってPOST形式でサーバにパラメータを渡そうとしていますが、パラメータが渡せずに困っています。 HttpOpenRequestかHttpSendRequestがおかしいと思うのですが、自分では見当がつきません。 よければ何処に問題があるのか教えてください。 環境:vc++2005 int DoHttpRequest( void ) { HINTERNET hInet, hSession, hRequest; DWORD dwTotal = 0; wchar_t param[] = L"type=1"; wchar_t header[] = L"Content-Type: application/x-www-form-urlencoded"; wchar_t accept[] = L"Accept: */*"; // 使ってない BOOL flag; Console::WriteLine( "Http接続START" ); //インターネット(WinInet)初期化 hInet = InternetOpen( NULL, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { Console::WriteLine( "エラー1" ); return -1; } // サーバへ接続 hSession = InternetConnect( hInet, L"192.168.11.25", 9999, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0 ); if( hSession == NULL ) { Console::WriteLine( "エラー2" ); InternetCloseHandle(hInet); return -1; } //HTTPセッションの開始, 指定のURLオープン hRequest = HttpOpenRequest( hSession, L"POST", L"/sample/service.php", NULL, NULL, NULL, INTERNET_FLAG_NO_CACHE_WRITE, 0 ); if (hRequest == NULL) { Console::WriteLine( "エラー3" ); InternetCloseHandle(hSession); InternetCloseHandle(hInet); return -1; } // 送信 flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param )); if( flag == FALSE ) { Console::WriteLine( "エラー4" ); InternetCloseHandle(hRequest); InternetCloseHandle(hSession); InternetCloseHandle(hInet); return -1; } //インターネットハンドルの解放 InternetCloseHandle( hRequest ); InternetCloseHandle( hSession ); InternetCloseHandle( hInet ); Console::WriteLine( "Http接続END" ); return 0; }

  • _ab
  • お礼率16% (2/12)

質問者が選んだベストアンサー

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

なるほど、第2引数と第4引数で指定されたものはそのように出力されるのですか…。 第2引数では追加のリクエストヘッダ(複数の場合はおそらく\r\nで結合して)を、第4引数ではHTTPBodyに相当するものを…ですか。 MSDNによると… 第3引数は >dwHeadersLength >[in] Size of the additional headers, in TCHARs. If this parameter is -1L and lpszHeaders is not NULL, the function assumes that lpszHeaders is zero-terminated (ASCIIZ), and the length is calculated. See Remarks for specifics. ということでTCHAR単位で、第5引数は >dwOptionalLength >[in] Size of the optional data, in bytes. This parameter can be zero if there is no optional data to send. ということでByte単位で渡す必要があるようです。 sizeof( param ) では、param[]には'\0'も含まれるので14になったようです。 wchar_t配列ではなく、charの配列でstrlen()でよいのではないでしょうか?

_ab
質問者

お礼

返信ありがとうございます。 おかげで解決することができました。 最終的に以下の変更でパラメータを渡すことができました。 >char param[] = "type=1"; >wchar_t header[] = L"Content-Type: application/x-www-form-urlencoded"; // char型だと12150エラー発生 >flag = HttpSendRequest( hRequest, header, wcslen( header ), param, strlen( param )); ヘッダーは以下のようになっていました。 >POST /sample/service.php HTTP/1.1 >Content-Type: application/x-www-form-urlencoded >Host: 192.168.11.25:9999 >Content-Length: 6 >Cache-Control: no-cache > >type=1 ありがとうございました。

その他の回答 (1)

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

とりあえず、WireSharkなどでどのように送られいるか確認してみてはどうでしょう? WinInet系のAPIは使ったことないのですが… >wchar_t param[] = L"type=1"; >wchar_t header[] = L"Content-Type: application/x-​www-form-urlencoded"; >flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param )); だと、POSTリクエストには Content-Type: application/x-​www-form-urlencoded: type=1 と送られているような気がするのですが…。 header[]に記述されている分がリクエストヘッダの名前("Host:"とか"User-Agent:"とか)で、param[]に記述されているのがそのパラメータ…とか。 複数のリクエストヘッダの場合はどうなるんでしょうかね? # \r\nで連結…なんでしょうか。

_ab
質問者

補足

WireSharkでパケットを確認してみたところ、ヘッダがおかしい事は確認できました。 少し調べてみましたがまだ解決には至ってません。 調べた分を以下に記載させてもらいます。 >flag = HttpSendRequest( hRequest, header, wcslen( header ), param, wcslen( param )); この時のヘッダは以下でした。 >POST /sample/service.php HTTP/1.1 >Content-Type: application/x-www-form-urlencoded >Host: 192.168.11.25:9999 >Content-Length: 6 >Cache-Control: no-cache > >typ HttpSendRequestの第5引数をsizeofにするとヘッダーはちゃんとしたように見えました。 >flag = HttpSendRequest( hRequest, header, wcslen( header ), param, sizeof( param )); この時は以下でした。 >POST /sample/service.php HTTP/1.1 >Content-Type: application/x-www-form-urlencoded >Host: 192.168.11.25:9999 >Content-Length: 14 >Cache-Control: no-cache > >type=1 FORMからPOSTする分はちゃんと受け取るのでphpの方は正しいと思っています。 phpの受信コードは以下です。 >$_type = $_POST['type']; 何かありましたらまた返信を頂けると助かります

関連するQ&A

  • InternetOpenUrlについて

    InternetOpenUrlを同一プログラム内で繰り返し使おうと思っているのですがうまくいきません ちなみにソースは hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { perror("オープンエラー\n"); return -2; } //HTTPセッションの開始, 指定のURLオープン hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0); if (hUrl == NULL) { perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } GetHtml(hInet,hUrl); pNext=GetMeigara(); printf("%s\n",pNext); remove("html.txt"); //インターネットハンドルの解放 InternetCloseHandle(hUrl); InternetCloseHandle(hInet); while(pNext != NULL){ hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if (hInet == NULL) { perror("オープンエラー\n"); return -2; } hUrl = InternetOpenUrl(hInet, pNext, NULL, 0, 0, 0); if (hUrl == NULL) { perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } GetHtml(hInet,hUrl); pNext=GetMeigara(); remove("html.txt"); InternetCloseHandle(hUrl); InternetCloseHandle(hInet); if(pNext==NULL) break; } 見づらくて申し訳ありません ちなみにループの中のInternetOpenUrlでオープンエラーになります

  • VC++ HttpOpenRequest() 正しく終了しない。

    MFC-dllを作成してVBで使用しようと思っています。 DLLの中ではWebサーバーに接続してデータを取得して VBで使う感じです。 DLLの中でダイアログボックスを一個作ってその中で実際のサーバーとの通信を行います。次のコードはそのDLL中のダイアログボックスの中でボタンを押したとき実行される関数です。 動きとしてはサーバーに接続し、データを正しく取得できますが、問題はこのDLLを使っているVBプログラムが終了してもWindows タスクマネージャーを見ると終了されてない状態です(デスクトップ画面上では終了されています)。しばらくしたら『応答なし』になって結局2~3分たったら自動に消滅されるのですが何だか感じ悪いです。コードの中に何か問題があるかどうか教えてください。 Void CTest::GetA (){ CHAR buffer[2048]; DWORD dwRead; char Header[]="Content-Type: application/x-www-form-urlencoded\n"; char Data[]="name=JohnDoe"; HINTERNET hINet=InternetOpen("V1.0",INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0); HINTERNET hCon=InternetConnect(hINet,"localhost",8080,"","", INTERNET_SERVICE_HTTP,0,0); HINTERNET hData = HttpOpenRequest(hConnection,"POST","/test001.asp",NULL,NULL,NULL,INTERNET_FLAG_KEEP_CONNECTION,0); HttpSendRequest( hData, Header, strlen(Header),Data,strlen(Data)); while( InternetReadFile( hData, buffer, 255, &dwRead ) ) { if ( dwRead == 0 ) break; buffer[dwRead] = 0; m_strContents += buffer; } InternetCloseHandle(hCon); InternetCloseHandle(hINet); InternetCloseHandle(hData); }

  • WinInet.dll で HTTPS へ POST できません

     WinInet.dll を使って、HTTPS サーバーへデータを POST するプログラムを作っています。開発言語は VB6 です。  HttpSendRequest で 12029 エラーとなり原因が分かりません。  HTTP 通信テストツールの RESTTEST を使ったテストでは正常に終了しています(HTTPステータス 200 が返っている)ので、回線やインターネット設定(ファイヤーウォールの問題など)は問題ないと思われます。  ソースから手続きの部分だけ抜き出して、下記に示します。  (エラーチェックなどはソース上にはありますが、ここでは省いています)  手続き上何か抜けが無いかご指摘いただけると助かります。   'インターネットサービスをオープンする   lngWinINet = InternetOpen(vbNullString, _                INTERNET_OPEN_TYPE_PRECONFIG, _                vbNullString, _                vbNullString, _                0)   'HTTPサーバへ接続   lngHttpHnd = InternetConnect(lngWinINet, _                  "www.test.jp", _                  INTERNET_DEFAULT_HTTPS_PORT, _                  vbNullString, _                  vbNullString, _                  INTERNET_SERVICE_HTTP, _                  0, _                  0)   'リクエストを初期化   Dim tmpURL As String * 255   Dim lngSecFlag As Long   lngSecFlag = INTERNET_FLAG_SECURE Or _          INTERNET_FLAG_IGNORE_CERT_CN_INVALID Or _          INTERNET_FLAG_IGNORE_CERT_DATE_INVALID   tmpURL = "/testdir/test.php"   lngReqHnd = HttpOpenRequest(lngHttpHnd, _                 "POST", _                 tmpURL, _                 "HTTP/1.1", _                 vbNullString, _                 0, _                 INTERNET_FLAG_RELOAD Or lngSecFlag, _                 0)   'リクエストを送信   Dim strHeader As String   Dim strPostData As String   strHeader = "Content-Type: application/x-www-form-urlencoded"   strPostData = "TEST1=aaa&TEST2=bbbbb"   Call HttpSendRequest(lngReqHnd, _              strHeader, _              Len(strHeader), _              strPostData, _              Len(strPostData))  手続き部分は、順番も含めて上記の通りです。  これ以外のことはやっていません。  これ以外にやっておかなければいけないことや、上記のやり方ではよくない部分などありましたら、ご教授いただけると助かります。  よろしくお願いします。

  • jpgファイルのダウンロード

    WWWサーバー上にあるjpgファイルを指定してそれをダウンロードするプログラムをつくっています。 jpgファイルが作成されることはされるのですが、中身をみることができない状態になってしまいます。 どこが悪いのかわかる方がおられましたらご教授お願いします。 <ソースコード> #include <windows.h> #include <stdio.h> #include <wininet.h> int main(void) { HINTERNET hInet, hUrl; char szBuf[128], szUrl[128], *lpszSrc; DWORD dwRead, dwTotal = 0; HGLOBAL hMem; FILE *file; printf("URL---- "); gets(szUrl); hInet = InternetOpen(TEXT("neko"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); if(hInet == NULL){ perror("オープンエラー\n"); return -2; } hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0); if(hUrl == NULL){ perror("URLオープンエラー\n"); return -3; } hMem = GlobalAlloc(GHND, 1); lpszSrc = (char*)GlobalLock(hMem); while(1){ InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf)-1, &dwRead); szBuf[dwRead] = '\0'; if(dwRead == 0){ break; } dwTotal += dwRead; hMem = GlobalReAlloc(hMem, dwTotal+1, GMEM_MOVEABLE); lpszSrc = (char*)GlobalLock(hMem); strcat(lpszSrc, szBuf); } if((file = fopen("test.jpg", "wb")) == NULL){ printf("ファイルオープンエラー\n"); goto end; } while(dwTotal){ fputc(*lpszSrc, file); lpszSrc++; dwTotal--; } fclose(file); end: GlobalUnlock(hMem); GlobalFree(hMem); InternetCloseHandle(hUrl); InternetCloseHandle(hInet); return 0; } <環境> Windows Vista VC++ 2005 EE

  • C#で独自の型を定義したい

    C# 2010 version 4.0を使用しています。 次のようなint型とstring型を混合したMixedという型を定義したいのですが、 public class Mixed { private int _TheInt = 0; public int TheInt { get { return _TheInt; } set { _TheInt = value; } } private string _TheString = null; public string TheString { get { return _TheString; } set { _TheString = value; } } public static implicit operator int(Mixed m) { return m.TheInt; } public static implicit operator Mixed(int x) { Mixed m = new Mixed(); m.TheInt = x; return m; } public static implicit operator string(Mixed m) { return m.TheString; } public static implicit operator Mixed(string x) { Mixed m = new Mixed(); m.TheString = x; return m; } } //Mixed m = 1; //Console.WriteLine(m); //これだとコンパイルエラーになる //Console.WriteLine(m.TheInt.ToString()); //「1」と表示される int i = 1; Console.WriteLine(i); //「1」と表示される object o = 1; Console.WriteLine(o); //「1」と表示される Console.WriteLineなどで表示する場合に 例えばint型なら int i = 1; Console.WriteLine(i); //「1」と表示される という具合にそのまま「1」と表示されます。 でもこのMixedの場合、 Mixed m = 1; Console.WriteLine(m.TheInt.ToString()); //「1」と表示される これでは「1」と表示されるのですが、 Console.WriteLine(m); //これだとコンパイルエラーになる このやり方だとエラーになります。 なんとかしてint型やobject型のようにToString()を使わずに 表示させることはできないでしょうか?

  • InternetOpengaが使えません・・・。

    すみません。 どーしてもできません。教えてください。 下記のプログラムを走らせたいのですが、エラーが直りません。 開発環境はVC++2008です。 プロジェクト新規でwin32コンソールアプリケーションを選択し、 空のプロジェクトを作成したあと、 WinInet.Libを追加しています。 下記のプログラムで、下記のようなエラーがでます。。。、 ------ ビルド開始: プロジェクト: readhtml, 構成: Debug Win32 ------ コンパイルしています... readhtml.cpp warning C4996: 'gets': This function or variable may be unsafe. Consider using gets_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\program files\microsoft visual studio 9.0\vc\include\stdio.h(279) : 'gets' の宣言を確認してください。 error C2664: 'InternetOpenW' : 1 番目の引数を 'const char [16]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 error C2664: 'InternetOpenUrlW' : 2 番目の引数を 'char [128]' から 'LPCWSTR' に変換できません。(新しい機能 ; ヘルプを参照) 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。 readhtml - エラー 2、警告 1 ========== ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ ========== ある本を見ながら、作成し、サンプルどおりに作っているのですが・・。 #include <windows.h> #include <stdio.h> #include <wininet.h> int main() { HINTERNET hInet,hUrl; char szBuf[128],szUrl[128],*lpszSrc; DWORD dwRead,dwTotal = 0; HGLOBAL hMem; //目的のURLの入力 printf("URL---"); gets(szUrl); //インターネット(WinInet)の開始 hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG, NULL,NULL,0); if (hInet == NULL){ perror("オープンエラー\n"); return -2; } //HTTPセッションの開始、指定のURLオープン hUrl = InternetOpenUrl(hInet,szUrl,NULL,0,0,0); if (hUrl == NULL){ perror("URLオープンエラー\n"); InternetCloseHandle(hInet); return -3; } //lpszSrcに1バイトのみ確保 hMem = GlobalAlloc(GHND,1); lpszSrc = (char *)GlobalLock(hMem); //読み出すものがなくなるまで読み出す while(1){ InternetReadFile( hUrl, szBuf, (DWORD)sizeof(szBuf) - 1 , &dwRead); szBuf[dwRead] = '\0'; //読み出すものがなくなたのでループ脱出 if (dwRead == 0){ break; } //必要バイト数の計算 dwTotal += dwRead; //確保領域の大きさ変更 hMem = GlobalReAlloc(hMem, dwTotal + 1, GMEM_MOVEABLE); if (hMem == NULL){ perror("再アロケート失敗\n"); } lpszSrc = (char *)GlobalLock(hMem); if (lpszSrc == NULL) { perror("メモリ確保に失敗\n"); break; } strcat(lpszSrc,szBuf); } //ソースの表示 printf("%s\n",lpszSrc); //メモリの開放 GlobalUnlock(hMem); GlobalFree(hMem); //インターネットハンドルの開放 InternetCloseHandle(hUrl); InternetCloseHandle(hInet); return 0 ; }

  • Visual C++ 2008 Express Editionの”hello worldのプログラム”

    CUIのプロジェクト作成で自動的に // cui_test.cpp : メイン プロジェクト ファイルです。 #include "stdafx.h" using namespace System; int main(array<System::String ^> ^args) { Console::WriteLine(L"Hello World"); return 0; } このようなプログラミングができて一つ疑問ができたのですが、 ”Console::WriteLine(L"Hello World");” System::Console:: のメソッドの中にある ”WriteLine(L"Hello World");” なぜ”(L"Hello World")”という引数の書き方をしているのですか? ”L”と”"Hello World"”というのは別々の引数として登録しているのでしょうか? オブジェクトブラウザでSystem::Console:: WriteLineを検索したのですが、18種類あってどれを使っているのかわかりません。 教えてくださいよろしくお願いいたします。

  • 配列からNULL以外のキーを取得したいのですが……

    配列からNULL以外のキーを取得したいです。 [0, 3]を期待しているのに、[0, 3: 3] で返ってきます。 なんででしょうか? function test(data) {  var result = [];  for (var i = 0, l = data.length; i < l; i++) {   if(data[i] !== null){    result[i] = i;   }  }  return result; } var data = ["1", null, null, "5"]; var last = test(data); console.log(last); ・console.logだから? ・もしそうなら、どうして[ 0: 1, 3: 3] ではないのでしょうか?

  • c#でサンプルゲームを作ってみた

    c#でサンプルゲームを作ってみたのですがエラーがでるので間違っている所を指摘してくださいm(__)m using System; class test1 { public int HP; public int ATK; public int DF; } public class test2 { public static void Main() { test1 player1 = new test1(); test1 player2 = new test1(); player1.HP = 150; player2.HP = 150; char ch; char ken; char zyuu; char chois; int buki; for(;;){ do{ Console.WriteLine(" 使う武器を選んでください"); Console.WriteLine("¥n"); Console.WriteLine(" 1. 刀 "); Console.WriteLine("¥n"); Console.WriteLine(" 2. 拳銃 "); Console.WriteLine("¥n"); Console.WriteLine(" 3. 素手 "); Console.WriteLine(" 終了させたい場合は e"); do{ ch = (char) Console.Read(); } while(ch == '¥n' | ch == '¥r'); }while(ch < '1' | ch > '3' & ch != 'n'); if(ch == 'n') break; Console.WriteLine("¥n"); switch(ch){ case '1': Console.WriteLine(" どの刀を使いますか?"); Console.WriteLine(" 1. 太刀"); Console.WriteLine(" 2薙刀"); ken = (char) Console.Read(); while(ken == '¥n' | ken == '¥r'); Console.WriteLine("¥n"); switch(ken){ case '1': buki = 15; break; case '2': buki = 14; break; } case '2': Console.WriteLine(" どの銃を使いますか?"); Console.WriteLine(" 1.マシンガン"); Console.WriteLine(" 2.リボルバー"); zyuu = (char) Console.Read(); while(zyuu == '¥n' | zyuu == '¥r'); Console.WriteLine("¥n"); switch(zyuu){ case'1': buki = 10; break; case'2': buki = 15; break; } case'3': buki = 8; break; } Console.WriteLine("敵が現れた!"); for(;;){ if(plyer1.HP < 0) break; else(player2.HP < 0 ) break; Console.WriteLine(" 1.攻撃¥n 2.防御"); chois = (char) Console.Read(); while(chois == '¥n' | chois == '¥r'); Console.WriteLine("¥n"); switch(chois){ case'1': Console.WriteLine("player1の攻撃!!"); player2.HP = player2.HP - (buki + 10) - 5; Console.WriteLine("%d, player2.HP") ; Console.WriteLine("player2の攻撃!!"); player1.HP = player1.HP - (20 - 5); break; case'2': Console.WriteLine(" player1はガードした!!"); Console.WriteLine("player2の攻撃!!"); Console.WriteLine(" しかしplayer1は攻撃を防いだ!"); break; } } } } }

  • WinInetのInternetOpenUrl関数が正常に動作しない。

    ネットワーク上のHTMLソースを取得しようとしています。InternetOpenUrl関数が動作せず、常にNULLが返ってきます。 環境は、WindowsXP、WindowsCE Platform Builder です。 void Get_HTML(){ HINTERNET hInternet; HINTERNET hFile; char Buff[1000]; DWORD ReadSize; BOOL bResult; //WinInetの初期化 char *agent ="WININET Sample Program"; hInternet = InternetOpen( (LPCWSTR)agent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0 ); if( hInternet == NULL ){ printf("InternetOpen Error \n"); } //ネット接続チェック if( InternetAttemptConnect(0) != ERROR_SUCCESS { printf("インターネットに接続できません。\n"); } else{ printf("インターネットに接続できる\n"); } //URLオープン char open_url="http://www.sample.com/sam1.html"; hFile = InternetOpenUrl( hInternet, (LPCWSTR)open_url, NULL, 0, INTERNET_FLAG_RELOAD, 0 ); printf("%s",(LPCWSTR)open_url); if( hFile == NULL ){ printf(" InternetOpenUrl ERROR \n"); } } InternetOpenUrl関数の戻り値がNULLになりReadを することが出来ません。 解決方法よろしくお願い致します。

専門家に質問してみよう