いろんなものはつながっている

ネットワークプログラミング基礎 HTTP/FTP プログラミング

「猫でもわかるネットワークプログラミン」を参考にWinInetを用いたHTTPプログラミングをやってみた。

手順は、
1.InternetOpen関数でWinInetを開始する。
2.InternetOpenUrl関数でセッションをオープンする。
3.InernetReadFile関数でデータを読み出す。
4.最後にInternetCloseHandleでハンドルを閉じる
であり、ソケットを意識せずにHTTPクライアントのプログラミングができる。

サイトに接続してページの内容をローカルのファイルに保存してみた。

// HTTPプログラミングサンプル

#include "stdafx.h"
#include "windows.h"
#include "wininet.h"

const int BUFF_SIZE = 128;

int ConvertWidetoMultiByte(TCHAR* szBuf);

int _tmain(int argc, _TCHAR* argv[])
{

	HINTERNET hInet, hUrl;

	// URL
	TCHAR szUrl[] = _T("http://www.yahoo.co.jp/");
	
	// インターネット接続の開始
	hInet = InternetOpen(_T("sample"), INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
	if(hInet == NULL){
		return -1;
	}

	// HTTPセッションの開始
	hUrl = InternetOpenUrl(hInet, szUrl, NULL, 0, 0, 0);
	if(hUrl == NULL){
		InternetCloseHandle(hInet);
		return -1;
	}

	// ヘッダーの読み出し
	TCHAR szHeaderBuf[1024];
	DWORD HeaderSize;
	if(!HttpQueryInfo(hUrl, HTTP_QUERY_CONTENT_TYPE, szHeaderBuf, &HeaderSize, NULL)){
		return -1;
	}

	// 読み出し
	TCHAR szBuf[BUFF_SIZE];
	DWORD dwRead;
	FILE* fp = _tfopen(_T("c:\\temp\\xyz.txt"), _T("w"));
	if(fp == NULL) return -1;
	while(1){
		InternetReadFile(hUrl, szBuf, (DWORD)(sizeof(szBuf)/sizeof(TCHAR)) - 1, &dwRead);
		if(dwRead == 0) break;
		szBuf[dwRead] = _T('\0');
		ConvertWidetoMultiByte(szBuf);  // utf-8の場合
		_ftprintf(fp, _T("%s"), szBuf);
	}

	// インターネットハンドルの解法
	InternetCloseHandle(hUrl);
	InternetCloseHandle(hInet);

	return 0;
}


int ConvertWidetoMultiByte(TCHAR* szBuf)
{
  // 変換
    char szMultiBuf[BUFF_SIZE];

    const int nWideByte = MultiByteToWideChar( CP_UTF8, 0, (LPCSTR)szBuf, -1, NULL, NULL );
    LPWSTR lpw = new WCHAR[nWideByte];
    MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)szBuf, -1, lpw, nWideByte);

    const int nMultiByte = WideCharToMultiByte( CP_ACP, 0, lpw, -1, NULL, 0, NULL, NULL );
    LPSTR lpa = new char[nMultiByte];

    const int nMultiCount = ::WideCharToMultiByte( CP_ACP, 0, lpw, -1, lpa, nMultiByte, NULL, NULL );

    ::strcpy_s(szMultiBuf, BUFF_SIZE, lpa);

    delete[] lpa;
    delete[] lpw;

	printf("%s", szMultiBuf);

	return 0;
}

同様にFTPのプログラミングもしてみた。
手順はHTTPと似ていて
1.InternetOpen関数でFTPセッションをオープンする
2.InternetConnect関数でFTPセッションハンドルを取得する
3.FtpSetCurrentDirectory関数で現在のFTPのディレクトリをセットする。
4.FtpGetFile関数でファイルをダウンロードする。
5.InternetCloseHandle関数でFTPとインターネットをクローズする。
となる。

// FTPプログラミングサンプル
//
#pragma comment(lib, "wininet.lib");

#include "stdafx.h"
#include "windows.h"
#include "wininet.h"

int _tmain(int argc, _TCHAR* argv[])
{
	HINTERNET hInet, hFTP;

	// インターネット接続の開始
	hInet = InternetOpen(_T("sample"), INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);	// 
	if(hInet == NULL){
		return -1;
	}

	// FTPサーバに接続する
	TCHAR szFTPServer[]=_T("ftp.riken.jp");
	hFTP = InternetConnect(hInet, szFTPServer, INTERNET_INVALID_PORT_NUMBER, 
		"anonymous", "password", INTERNET_SERVICE_FTP, INTERNET_FLAG_PASSIVE, 0);
	if(hFTP == NULL){
		InternetCloseHandle(hInet);
		return -1;
	}

	// FTPサーバのカレントディレクトリの設定
	TCHAR szBaseDir[]=_T("/Linux/ubuntu/project");
	if(!FtpSetCurrentDirectory(hFTP, szBaseDir)){
		InternetCloseHandle(hFTP);
		InternetCloseHandle(hInet);
		return -1;
	}

	// ファイルを取得
	TCHAR szDownLoadFile[]  = _T("ubuntu-archive-keyring.gpg");
	TCHAR szLocalFilePath[] = _T("c:\\temp\\zzz.gpg");
	if(!FtpGetFile(hFTP, szDownLoadFile, szLocalFilePath, 
		TRUE, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_BINARY, 0)){
		InternetCloseHandle(hFTP);
		InternetCloseHandle(hInet);
		return -1;
	}

	InternetCloseHandle(hFTP);
	InternetCloseHandle(hInet);
	
	return 0;
}

関連記事

コメント

  1. この記事へのコメントはありません。

  1. この記事へのトラックバックはありません。

スポンサード リンク

カテゴリー

スポンサード リンク