首页 > 编程 > .NET > 正文

构造.NET环境下的网页下载器 (2)

2024-07-10 13:05:17
字体:
来源:转载
供稿:网友
,欢迎访问网页设计爱好者web开发。三.网页下载器实例介绍:

  最后,我就综合以上.net网络编程的一些知识,向大家展示一个很好的实例。该实例是一个运用socket的基于同步模式的客户端应用程序,它首先通过解析服务器的ip地址建立一个终结点,同时创建一个基于流套接字的socket连接,其运用的协议是tcp协议。通过该socket就可以发送获取网页的命令,再通过该socket获得服务器上默认的网页,最后通过文件流将获得的数据写入本机文件。这样就完成了网页的下载工作了

程序的代码如下:

using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;
using system.net;
using system.net.sockets;
using system.text;
using system.io;

namespace socketsample
{
/// <summary>
/// form1 的摘要说明。
/// </summary>

public class form1 : system.windows.forms.form
{
private system.windows.forms.label label1;
private system.windows.forms.label label2;
private system.windows.forms.button download;
private system.windows.forms.textbox serveraddress;
private system.windows.forms.textbox filename;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private system.componentmodel.container
components = null;
public form1()
{
//
// windows 窗体设计器支持所必需的
//
initializecomponent();

//
// todo: 在 initializecomponent
// 调用后添加任何构造函数代码
}

/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.dispose();
}
}
base.dispose( disposing );
}

#region windows form designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器修改
/// 此方法的内容。
/// </summary>
private void initializecomponent()
{
this.label1 = new system.windows.
forms.label();
this.label2 = new system.windows.
forms.label();
this.download = new system.windows.
forms.button();
this.serveraddress = new system.windows.
forms.textbox();
this.filename = new system.windows.
forms.textbox();
this.suspendlayout();
//
// label1
//
this.label1.location = new system.drawing.
point(16, 24);
this.label1.name = "label1";
this.label1.size = new system.drawing.
size(80, 23);
this.label1.tabindex = 0;
this.label1.text = "服务器地址:";
this.label1.textalign = system.drawing.
contentalignment.middleright;
//
// label2
//
this.label2.location = new system.drawing.
point(16, 64);
this.label2.name = "label2";
this.label2.size = new system.drawing.
size(80, 23);
this.label2.tabindex = 1;
this.label2.text = "本地文件名:";
this.label2.textalign = system.drawing.
contentalignment.middleright;
//
// download
//
this.download.location = new system.
drawing.point(288, 24);
this.download.name = "download";
this.download.tabindex = 2;
this.download.text = "开始下载";
this.download.click += new system.
eventhandler(this.download_click);
//
// serveraddress
//
this.serveraddress.location = new system.
drawing.point(96, 24);
this.serveraddress.name = "serveraddress";
this.serveraddress.size = new system.
drawing.size(176, 21);
this.serveraddress.tabindex = 3;
this.serveraddress.text = "";
//
// filename
//
this.filename.location = new system.
drawing.point(96, 64);
this.filename.name = "filename";
this.filename.size = new system.
drawing.size(176, 21);
this.filename.tabindex = 4;
this.filename.text = "";
//
// form1
//
this.autoscalebasesize = new system.
drawing.size(6, 14);
this.clientsize = new system.drawing.
size(376, 117);
this.controls.addrange(new system.windows.
forms.control[] {
this.filename,
this.serveraddress,
this.download,
this.label2,
this.label1});
this.name = "form1";
this.text = "网页下载器";
this.resumelayout(false);
}
#endregion

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[stathread]
static void main()
{
application.run(new form1());
}

private string dosocketget(string server)
{
//定义一些必要的变量以及一条要发送到服务器的字符串
encoding ascii = encoding.ascii;
string get = "get / http/1.1/r/nhost: "
+server+"/r/nconnection: close/r/n/r/n";
byte[] byteget = ascii.getbytes(get);
byte[] recvbytes = new byte[256];
string strretpage = null;

//获取服务器相关的ip地址列表,其中第一项即为我们所需的
ipaddress hostadd = dns.resolve(server).
addresslist[0];

//根据获得的服务器的ip地址创建一个终结点,端口为默认的80
ipendpoint ephost = new ipendpoint
(hostadd, 80);

//创建一个socket实例
socket s = new socket(addressfamily.
internetwork, sockettype.stream,
protocoltype.tcp );
try
{
//用上面所取得的终结点连接到服务器
s.connect(ephost);
}
catch(exception se)
{
messagebox.show("连接错误:"+se.
message,"提示信息",messageboxbuttons.
retrycancel,messageboxicon.information);
}

if (!s.connected)
{
strretpage = "不能连接到服务器!";
return strretpage;
}

try
{
//向服务器发送get命令
s.send(byteget, byteget.length,
socketflags.none);
}
catch(exception ce)
{
messagebox.show("发送错误:"+ce.
message,"提示信息",messageboxbuttons.
retrycancel,messageboxicon.information);
}

//接收页面数据,直到所有字节接收完毕
int32 bytes = s.receive(recvbytes,
recvbytes.length, 0);
strretpage = "以下是在服务器" + server +
"上的默认网页:/r/n";
strretpage = strretpage + ascii.getstring
(recvbytes, 0, bytes);

while (bytes > 0)
{
bytes = s.receive(recvbytes,
recvbytes.length, socketflags.none);
strretpage = strretpage + ascii.
getstring(recvbytes, 0, bytes);
}

//禁用并关闭socket实例
s.shutdown(socketshutdown.both);
s.close();
return strretpage;
}

private void download_click(object sender, system.
eventargs e)
{
//将所读取的字符串转换为字节数组
byte[] content=encoding.ascii.getbytes
(dosocketget(serveraddress.text));
try
{
//创建文件流对象实例
filestream fs=new filestream
(filename.text,filemode.openorcreate,fileaccess.
readwrite);
//写入文件
fs.write(content,0,content.length);
}
catch(exception fe)
{
messagebox.show("文件创建/写入错误:
"+fe.message,"提示信息",messageboxbuttons.
retrycancel,messageboxicon.information);
}
}
}
}



其中主要的函数为dosocketget(),首先程序在响应"开始下载"的事件处理函数download_click(),调用dosocketget()函数,该函数完成了套接字的创建、连接、与主机的通讯-即获得主机上的网页、禁用、关闭等功能。在调用完dosocketget()函数后,download_click()函数创建一个filestream对象,并试图将dosocketget()函数返回的网页文件以字节数组的形式写到本机文件中,最终形成在本机上的一个html文件,这样就完成了一个网页文件的下载工作了。

  不过这个程序的功能比较简单,不能作为真正的网页浏览器用,网页文件下载后还是要用ie等浏览器才能打开。然而作为一个解释.net底层网络编程的实例绝对是一个好例子,所以希望读者能好好研究,同时读者还可以添加文件下载进度条等以完善本程序。

  注:以上程序在windows 2000服务器版、visual studio.net中文正式版下调试通过。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表