2010.05.06

【正誤情報】2.3節 GUI版HTTPクライアント(2004/1/31更新)

猫でもわかるネットワークプログラミング

『猫でもわかるネットワークプログラミング』のサンプルコードに下記の事象が確認されています。


■対象プログラム
2.3節 GUI版HTTPクライアント html02.exe(p.22)

■事象
2回以上URL取得を実行した場合、プログラムの終了時に正常にメモリオブジェクトが解放されない。

■原因
メモリオブジェクトの解放処理がWM_CLOSEメッセージ発生時のみであるため、最後に取得したメモリオブジェクト以外は解放されない。

■改修方法
MyConnect関数は、下記のコードを使用してください。(改修ファイルのダウンロード html02b.lzh 17KB)

int MyConnect()
{
	HINTERNET hInet, hUrl;
	char szBuf[32];
	DWORD dwRead;
	HGLOBAL hTemp;
	if (hMem != NULL) {
        GlobalUnlock(hMem);
        if (!(hMem = GlobalFree(hMem))) {
            MessageBox(g_hWnd, "前回確保したメモリを解放しました。n"
                "新たにメモリを確保します。",
                "メモリ解放成功", MB_OK);
        } else {
            MessageBox(g_hWnd, "前回確保したメモリの解放に失敗しました",
                "Error", MB_OK);
            return -1;
        }
    }
	hMem = GlobalAlloc(GHND, 1);
	lpszSrc = (char *)GlobalLock(hMem);
	if (lpszSrc == NULL) {
		MessageBox(g_hWnd, "Error", "Error", MB_OK);
		return -1;
	}
	int nTotal = 0;
	hInet = InternetOpen("nekodemo-wakaru", INTERNET_OPEN_TYPE_PRECONFIG,	
		NULL, NULL, 0);
	if (hInet == NULL) {
		MessageBox(g_hWnd, "オープンエラー", "Error", MB_OK);
		return -1;
	}
	hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0);
	if (hUrl == NULL) {
		MessageBox(g_hWnd, "URLオープンエラー", "Error", MB_OK);
		InternetCloseHandle(hInet);
		return -2;
	}
	while (1) {
		InternetReadFile(hUrl, szBuf, (DWORD)sizeof(szBuf) - 1, &dwRead); 
		szBuf[dwRead] = '';
		if (dwRead == 0)
			break;
		nTotal += dwRead;
		hTemp = GlobalReAlloc(hMem, (SIZE_T)nTotal+1, GMEM_MOVEABLE);
		if (hTemp == NULL) {
			MessageBox(g_hWnd, "再アロケート失敗", "Error", MB_OK);
			return -3;
		}
		hMem = hTemp;
		lpszSrc = (char *)GlobalLock(hMem);
		strcat(lpszSrc, szBuf);
		
	}
	InvalidateRect(g_hWnd, NULL, TRUE);
	InternetCloseHandle(hUrl);
	InternetCloseHandle(hInet);
	return 0;
}

ダウンロード

html02b.lzh (17KB:改修ソースコード&実行ファイル)