使用其他函数完善实验1下载功能
-
使用WinInet系列函数实现下载
InternetOpen
InternetOpenUrl
InternetReadFile
InternetCloseHandle -
使用socket函数实现下载
WSAStartup
socket
connect
send
recv
closesocket
WSACleanup
CSocket
CAsyncSocket
python socket
import socket
s = socket.socket()
s.connect()
s.sendall()
s.recv()
s.close()
备选:
3. 在驱动层自动发包,实现网络功能
4. 自定义协议栈,利用IOCTL向底层发包实现网络功能
tcpip.sys
一: 使用WinInet系列函数实现下载
1.实验原理:
InternetOpen 概况:初始化一个应用程序,以使用 WinINet 函数。
HINTERNET InternetOpen(
(ByVal sAgent As String, _
ByVal lAccessType As Long, _
ByVal sProxyName As String, _
ByVal sProxyBypass As String, _
ByVal lFlags As Long) As Long
);
sAgent指定调用 WinINet 函数的应用程序或入口。该入口用作HTTP协议中用户代理项。
lAccessType访问要求类型
sProxyName指定了当lAccessType类型INTERNET_OPEN_TYPE_PROXY时,代理服务器的名字。
sProxyBypass指向一个字符串,它指定一个可选的主机名列表或IP地址,列表可包括未知元素。
lFlags该参数可为下列值的任意组合:
INTERNET_FLAG_ASYNC 仅能用于作用在该函数返回的句柄的子句柄上的异步请求。
INTERNET_FLAG_FROM_CACHE 不做网络请求。所有的实体都由缓存返回。如果请求条目不在缓存中,一个适当的错误将返回。
INTERNET_FLAG_OFFLINE 与 INTERNET_FLAG_FROM_CACHE 一样。
InternetOpenUrl通过一个完整的FTP,Gopher或HTTP网址打开一个资源。
HINTERNET InternetOpenUrl
( HINTERNET hInternet ,
LPCTSTR lpszUrl ,
LPCTSTR lpszHeaders ,
DWORD dwHeadersLength ,
DWORD dwFlags ,
DWORD_PTR dwContext)
hInternet
当前的 Internet 会话句柄。句柄必须由前期的 InternetOpen 调用返回。
lpszUrl
一个空字符结束的字符串变量的指针,指定读取的网址。只有以ftp:, gopher:, http:, 或者 https: 开头的网址被支持。
lpszHeaders
一个空字符结束的字符串变量的指针,指定发送到HTTP服务器的头信息。欲了解更多信息,请参阅HttpSendRequest函数里lpszHeaders参数的说明。
dwHeadersLength
dwFlags
此参数可为下列值之一。
dwContext
一个指向一个应用程序定义的值,将随着返回的句柄,一起传递给回调函数。
返回值
如果已成功建立到FTP,Gopher,或HTTP URL的连接,返回一个有效的句柄,如果连接失败返回NULL。要检索特定的错误讯息,请GetLastError 。要确定为什么对服务器的访问被拒绝,请调用InternetGetLastResponseInfo。
InternetReadFile
函数介绍指从一个由InternetOpenUrl,FtpOpenFile, 或HttpOpenRequest函数打开的句柄中读取数据。
BOOL InternetReadFile( __in HINTERNET hFile,
__out LPVOID lpBuffer,
__in DWORD dwNumberOfBytesToRead,
__out LPDWORD lpdwNumberOfBytesRead
);
Parameters
hFile[in]
由InternetOpenUrl,FtpOpenFile, 或HttpOpenRequest函数返回的句柄.
lpBuffer[out]
缓冲器指针
dwNumberOfBytesToRead[in]
欲读数据的字节量。
lpdwNumberOfBytesRead[out]
接收读取字节量的变量。该函数在做任何工作或错误检查之前都设置该值为零
返回值编辑
成功:返回TRUE,失败,返回FALSE
InternetCloseHandle函数:关闭两个连接句柄
2.代码
#include “stdafx.h”
#include
#include <Windows.h>
#include <wininet.h>
using namespace std;
#pragma comment(lib, “wininet.lib”)
int main()
{
DWORD dwBytesRead = 0;
char buffer[1025];
BOOL hwrite = 0;
DWORD written = 0;
DWORD byteread = 0;
BOOL internetreadfile = 0;
HINTERNET hNet = InternetOpen(
"testing", // 1 LPCTSTR lpszCallerName
PRE_CONFIG_INTERNET_ACCESS, // 2 DWORD dwAccessType
NULL, // 3 LPCTSTR lpszProxyName
INTERNET_INVALID_PORT_NUMBER, // 4 INTERNET_PORT nProxyPort
0 // 5 DWORD dwFlags
);
HINTERNET hUrlFile = InternetOpenUrl(
hNet, // 1 HINTERNET hInternetSession
"http://10.3.1.91/hi.exe", // 2 LPCTSTR lpszUrl
NULL, // 3 LPCTSTR lpszHeaders
0, // 4 DWORD dwHeadersLength
INTERNET_FLAG_RELOAD, // 5 DWORD dwFlags
0 // 6 DWORD dwContext
);
HANDLE createfile;
createfile = CreateFile("C:\\Users\\Administrator\\Desktop\\hahaha.exe", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (createfile == INVALID_HANDLE_VALUE) {
cout << "Create File failed!" << endl;
}
while (1) {
internetreadfile = InternetReadFile(hUrlFile, buffer, sizeof(buffer), &byteread);
if (byteread == 0)
break;
hwrite = WriteFile(createfile, buffer, sizeof(buffer), &written, NULL);
if (hwrite == 0) {
cout << "Write to file failed!" << endl;
}
}
InternetCloseHandle(hUrlFile);
InternetCloseHandle(hNet);
return 0;
}
二:使用socket函数实现下载
1.原理