确定了远程设备的地址并选择了用于连接的端口后,应用程序可以尝试建立与远程设备的连接。下面的示例使用现有的 ipendpoint 实例与远程设备连接,并捕获可能引发的异常:
try {
s.connect(ipe);//尝试连接
}
//处理参数为空引用异常
catch(argumentnullexception ae) {
console.writeline("argumentnullexception : {0}", ae.tostring());
}
//处理操作系统异常
catch(socketexception se) {
console.writeline("socketexception : {0}", se.tostring());
}
catch(exception e) {
console.writeline("unexpected exception : {0}", e.tostring());
}
需要知道的是:socket 类支持两种基本模式:同步和异步。其区别在于:在同步模式中,对执行网络操作的函数(如 send 和 receive)的调用一直等到操作完成后才将控制返回给调用程序。在异步模式中,这些调用立即返回。
另外,很多时候,socket编程视情况不同需要在客户端和服务器端分别予以实现,在客户端编制应用程序向服务端指定端口发送请求,同时编制服务端应用程序处理该请求,这个过程在上面的阐述中已经提及;当然,并非所有的socket编程都需要你严格编写这两端程序;视应用情况不同,你可以在客户端构造出请求字符串,服务器相应端口捕获这个请求,交由其公用服务程序进行处理。以下事例语句中的字符串就向远程主机提出页面请求:
string get = "get / http/1.1\r\nhost: " + server + "\r\nconnection: close\r\n\r\n";
远程主机指定端口接受到这一请求后,就可利用其公用服务程序进行处理而不需要另行编制服务器端应用程序。
综合运用以上阐述的使用visual c#进行socket网络程序开发的知识,下面的程序段完整地实现了web页面下载功能。用户只需在窗体上输入远程主机名(dns 主机名或以点分隔的四部分表示法格式的 ip 地址)和预保存的本地文件名,并利用专门提供http服务的80端口,就可以获取远程主机页面并保存在本地机指定文件中。如果保存格式是.htm格式,你就可以在internet浏览器中打开该页面。适当添加代码,你甚至可以实现一个简单的浏览器程序。
实现此功能的主要源代码如下:
//"开始"按钮事件
private void button1_click(object sender, system.eventargs e) {
//取得预保存的文件名
string filename=textbox3.text.trim();
//远程主机
string hostname=textbox1.text.trim();
//端口
int port=int32.parse(textbox2.text.trim());
//得到主机信息
iphostentry ipinfo=dns.gethostbyname(hostname);
//取得ipaddress[]
ipaddress[] ipaddr=ipinfo.addresslist;
//得到ip
ipaddress ip=ipaddr[0];
//组合出远程终结点
ipendpoint hostep=new ipendpoint(ip,port);
//创建socket 实例
socket socket=new socket(addressfamily.internetwork,sockettype.stream,protocoltype.tcp);
try
{
//尝试连接
socket.connect(hostep);
}
catch(exception se)
{
messagebox.show("连接错误"+se.message,"提示信息
,messageboxbuttons.retrycancel,messageboxicon.information);
}
//发送给远程主机的请求内容串
string sendstr="get / http/1.1\r\nhost: " + hostname +
"\r\nconnection: close\r\n\r\n";
//创建bytes字节数组以转换发送串
byte[] bytessendstr=new byte[1024];
//将发送内容字符串转换成字节byte数组
bytessendstr=encoding.ascii.getbytes(sendstr);
try
{
//向主机发送请求
socket.send(bytessendstr,bytessendstr.length,0);
}
catch(exception ce)
{
messagebox.show("发送错误:"+ce.message,"提示信息
,messageboxbuttons.retrycancel,messageboxicon.information);
}
//声明接收返回内容的字符串
string recvstr="";
//声明字节数组,一次接收数据的长度为1024字节
byte[] recvbytes=new byte[1024];
//返回实际接收内容的字节数
int bytes=0;
//循环读取,直到接收完所有数据
while(true)
{
bytes=socket.receive(recvbytes,recvbytes.length,0);
//读取完成后退出循环
if(bytes<=0)
break;
//将读取的字节数转换为字符串
recvstr+=encoding.ascii.getstring(recvbytes,0,bytes);
}
//将所读取的字符串转换为字节数组
byte[] content=encoding.ascii.getbytes(recvstr);
try
{
//创建文件流对象实例
filestream fs=new filestream(filename,filemode.openorcreate,fileaccess.readwrite);
//写入文件
fs.write(content,0,content.length);
}
catch(exception fe)
{
messagebox.show("文件创建/写入错误:"+fe.message,"提示信息",messageboxbuttons.retrycancel,messageboxicon.information);
}
//禁用socket
socket.shutdown(socketshutdown.both);
//关闭socket
socket.close();
}
}
程序在windowsxp中文版、.net frameworkd 中文正式版、visual studio.net中文正式版下调试通过
关于作者
宋华,96年毕业于承德石油学院电子与电气系计算机应用专业,同年进入中国石油天然气集团公司吐哈油田工作,一直从事网络规划与建设、网站架构与设计,现专门从事internet应用程序开发及windows应用程序开发。
2
您可能感兴趣的文章:
如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!
网友评论