C#网络编程
1.WebClient类
(1)WebClient类的主要方法
DownloadXXX()方法:下载URI资源文件
OpenXXX()方法:打开URI资源流
UploadXXX()方法:上传资源到URI
(2)DownloadData()方法
1 2 3 4 5 6 7 8 9 10 11
| class Program { static void Main(string[] args) { WebClient web = new WebClient(); byte[] temp = web.DownloadData("http://www.baidu.com"); string Response = Encoding.UTF8.GetString(temp); Console.WriteLine(Response); Console.Read(); } }
|
(3)OpenRead()方法
1 2 3 4 5 6 7 8 9 10 11 12
| class Program { static void Main(string[] args) { WebClient web = new WebClient(); Stream st = web.OpenRead("http://www.baidu.com"); StreamReader sr = new StreamReader(st); string Response = sr.ReadToEnd(); Console.WriteLine(Response); Console.Read(); } }
|
(4)UploadData()方法
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Program { static void Main(string[] args) { WebClient web = new WebClient(); string str = "测试"; byte[] response = web.UploadData("http://www.baidu.com", Encoding.Default.GetBytes(str)); Console.WriteLine(Encoding.Default.GetString(response)); Console.Read(); } }
|
(5)总结WebClient类
虽然WebClient类使用简单,但是其功能有限,特别是不能使用它提供身份验证证书。这样,在上传数据时问题就出现了,许多站点不接受没有身份验证的上传文件。这是由于WebClient类是非常一般的类,可以使用任意协议发送请求和接受响应(如:HTTP、FTP等)。但它不能处理特定于任何协议的任何特性,例如,专用于HTTP的cookie。如果想利用这些特性就需要使用WebRequest类与WebResponse类为基类的一系列类。
2.WebRequest类与WebResponse类
(1)WebRequest类与WebResponse类简介
WebRequest类与WebResponse类是抽象类,其子类对象代表某个特定URI协议的请求对象或响应对象。调用WebRequest.Create()方法得到WebResponse对象。调用WebResponse对象的GetResponse()方法得到WebResponse对象。
(2)使用示例
1 2 3 4 5 6 7 8 9 10 11 12
| class Program { static void Main(string[] args) { WebRequest req = WebRequest.Create("http://www.baidu.com"); WebResponse res = req.GetResponse(); Stream strm = res.GetResponseStream(); StreamReader sr = new StreamReader(strm); Console.WriteLine(sr.ReadToEnd()); Console.Read(); } }
|
(3)WebRequest类与WebResponse类的子类(继承结构)

(4)HttpWebRequest类与HttpWebResponse类使用示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Program { static void Main(string[] args) { string uri = "http://www.baidu.com"; HttpWebRequest httpRe = (HttpWebRequest)HttpWebRequest.Create(uri); HttpWebResponse httpRes = (HttpWebResponse)httpRe.GetResponse(); Stream strm = httpRes.GetResponseStream(); StreamReader sr = new StreamReader(strm); Console.WriteLine(sr.ReadToEnd()); Console.Read(); } }
|
(5)身份验证
如果需要把身份验证证书附带在请求中,就使用WebRequest类中的Credentials属性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Program { static void Main(string[] args) { WebRequest req = WebRequest.Create("http://www.baidu.com"); NetworkCredential cred = new NetworkCredential("userName", "password"); req.Credentials = cred; WebResponse res = req.GetResponse(); Stream strm = res.GetResponseStream(); StreamReader sr = new StreamReader(strm); Console.WriteLine(sr.ReadToEnd()); Console.Read(); } }
|
(6)使用代理
使用代理服务器需要用到WebRequest类中的Proxy属性,以及WebProxy对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Program { static void Main(string[] args) { WebRequest req = WebRequest.Create("http://www.baidu.com"); NetworkCredential cred = new NetworkCredential("userName", "password","Domain"); WebProxy wp = new WebProxy("192.168.1.100", true); req.Credentials = cred; req.Proxy = wp; WebResponse res = req.GetResponse(); Stream strm = res.GetResponseStream(); StreamReader sr = new StreamReader(strm); Console.WriteLine(sr.ReadToEnd()); Console.Read(); } }
|
(7)异步请求
若需要使用异步请求,就可以使用BeginGetRequestStream()、EndGetRequestStream()与BeginGetResponse()、EndGetResponse()方法。使用异步请求就不需要等待请求的响应,主线程不必阻塞可以直接向下执行。示例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Program { static void Main(string[] args) { WebRequest req = WebRequest.Create("http://www.baidu.com"); req.BeginGetResponse(new AsyncCallback(Callback), req); Console.WriteLine("异步请求已发送..."); Console.Read(); } private static void Callback(IAsyncResult ar) { Thread.Sleep(5000); WebRequest req = (WebRequest)ar.AsyncState; WebResponse res = req.EndGetResponse(ar); Stream strm = res.GetResponseStream(); StreamReader sr = new StreamReader(strm); Console.WriteLine(sr.ReadToEnd()); } }
|
3.WebBrowser控件
(1)使用WebBrowser控件
使用WebBrowser控件非常简单,如下图:

其按钮的单击事件代码如下:
1 2 3 4
| private void button1_Click(object sender, EventArgs e) { this.webBrowser1.Navigate("http://www.baidu.com"); }
|
(2)WebBrowser控件常用属性、方法与事件
WebBrowser控件常用的方法:Navigate():加载URI页面,GoBack():后退,GoForward():前进,Refresh():刷新,Stop():停止,GoHome():浏览主页。
WebBrowser控件的常用属性:Document:获取当前正在浏览的文档,DocumentTitle:获取当前正在浏览的网页标题,StatusText:获取当前状态栏的文本,Url:获取当前正在浏览的网址的Uri,ReadyState:获取浏览的状态。
WebBrowser控件的常用事件:DocumentCompleted:在WebBrowser控件完成加载文档时发生,XXXChanged:在XXX属性值更改时发生。
****注意****:得到了Document属性就可以直接操作网页里的元素了!
4.网络工具类(URL、IP、DNS)
(1)Uri与UriBuilder
Uri与UriBuilder类的主要区别是:Uri提供了很多只读属性,Uri对象被创建后就不能修改了;而UriBuilder类的属性较少,只允许构建一个完整的URI,这些属性可读写。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Program { static void Main(string[] args) { Uri uri = new Uri("http://www.baidu.com/s?wd=URI"); Console.WriteLine(uri.Query); Console.WriteLine(uri.AbsolutePath); Console.WriteLine(uri.Scheme); Console.WriteLine(uri.Port); Console.WriteLine(uri.Host); Console.WriteLine(uri.IsDefaultPort); UriBuilder urib = new UriBuilder(); urib.Host = uri.Host; urib.Scheme = uri.Scheme; urib.Path = uri.AbsolutePath; urib.Port = uri.Port; UriTest(uri); UriTest(urib.Uri); Console.Read(); } static void UriTest(Uri uri) { Console.WriteLine("==============" + uri + "开始==============="); Thread.Sleep(5000); HttpWebRequest httpweb = (HttpWebRequest)HttpWebRequest.Create(uri); HttpWebResponse res = (HttpWebResponse)httpweb.GetResponse(); Stream stream = res.GetResponseStream(); StreamReader strread = new StreamReader(stream); Console.WriteLine(strread.ReadToEnd()); Console.WriteLine("======================完成===================\n\n\n\n"); } }
|
(2)IPAddress、IPHostEntry 与Dns
IPAddress类提供了对IP地址的转换、处理等功能。IPHostEntry类的实例对象中包含了Internet主机的相关信息。Dns类提供了一系列静态的方法,用于获取提供本地或远程域名等功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Program { static void Main(string[] args) { IPAddress ip =IPAddress.Parse("202.108.22.5"); byte[] bit = ip.GetAddressBytes(); foreach (byte b in bit) { Console.Write(b+" "); } Console.WriteLine("\n"+ip.ToString()+"\n\n"); IPHostEntry iphe = Dns.GetHostEntry("www.microsoft.com"); Console.WriteLine("www.microsoft.com主机DNS名:" + iphe.HostName); foreach (IPAddress address in iphe.AddressList) { Console.WriteLine("关联IP:"+address); } Console.WriteLine("\n"); iphe = Dns.GetHostEntry(Dns.GetHostName()); Console.WriteLine("本地计算机名:" + iphe.HostName); foreach (IPAddress address in iphe.AddressList) { Console.WriteLine("关联IP:" + address); } Console.Read(); } }
|
(3)解码与编码(Encoding)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| class Program { static void Main(string[] args) { Encoding utf8 = Encoding.UTF8; Encoding gb2312 = Encoding.GetEncoding("GB2312"); string test = "编码解码测试 ABCDabcd!"; char[] source = test.ToCharArray(); int len = utf8.GetByteCount(source, 0, test.Length); byte[] result = new byte[len]; utf8.GetBytes(source, 0, test.Length, result, 0); foreach (byte b in result) { Console.Write("{0:X}", b); } Console.WriteLine(); Console.WriteLine(utf8.GetString(result)); EncodingInfo[] encodings = Encoding.GetEncodings(); foreach (EncodingInfo e in encodings) { Console.WriteLine(e.Name); } Console.WriteLine(Uri.EscapeUriString("http://www.baidu.com/s?wd=李志伟")); string temp = HttpUtility.UrlEncode("李志伟", gb2312); Console.WriteLine(temp + "-->" + HttpUtility.UrlDecode(temp, gb2312)); Console.Read(); } }
|
5.底层的网络协议类
(1)Socket
Socket:实现 Berkeley 套接字接口。
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Program { static void Main(string[] args) { Thread.Sleep(1000 * 2); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ie = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999); client.Connect(ie); byte[] data = new byte[1024]; int recv = client.Receive(data); Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv)); for (int i = 0; i < 20; i++) { client.Send(Encoding.UTF8.GetBytes(i + ":李志伟发送的消息!\n")); Console.WriteLine("发送消息数:" + i); Thread.Sleep(1000); } client.Shutdown(SocketShutdown.Both); client.Close(); Console.WriteLine("连接已断开!"); Console.Read(); } }
|
服务端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| class Program { static void Main(string[] args) { IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9999); Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); sock.Bind(ipep); sock.Listen(10); Console.WriteLine("已监听..."); while (true) { Socket client = sock.Accept(); Console.WriteLine("连接成功:" + client.RemoteEndPoint.ToString() + " -->" + client.LocalEndPoint.ToString()); byte[] data = Encoding.UTF8.GetBytes("欢迎!!!"); client.Send(data, data.Length, SocketFlags.None); while (client.Connected) { data = new byte[1024]; int recv = client.Receive(data); Console.WriteLine(Encoding.UTF8.GetString(data, 0, recv)); } client.Close(); } sock.Close(); } }
|
(2)NetworkStream、TcpClient与TcpListener
NetworkStream:提供用于网络访问的基础数据流。TcpClient:为TCP网络服务提供客户端连接。TcpListener:从TCP网络客户端侦听连接。
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Program { static void Main(string[] args) { Thread.Sleep(1000 * 2); for (int i = 0; i < 20; i++) { TcpClient tcpClient = new TcpClient(); tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 9999); Console.WriteLine(i + ":连接成功!"); NetworkStream ns = tcpClient.GetStream(); Byte[] sendBytes = Encoding.UTF8.GetBytes(i + ":李志伟发送的消息!\n"); ns.Write(sendBytes, 0, sendBytes.Length); ns.Dispose(); tcpClient.Close(); Console.WriteLine("已发送消息数:" + i); Thread.Sleep(1000); } Console.Read(); } }
|
服务端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Program { static void Main(string[] args) { IPAddress ip = IPAddress.Parse("127.0.0.1"); TcpListener listener = new TcpListener(ip, 9999); listener.Start(); Console.WriteLine("已开始侦听..."); while (true) { TcpClient client = listener.AcceptTcpClient(); Console.WriteLine("连接成功{0}-->{1}", client.Client.RemoteEndPoint.ToString(), client.Client.LocalEndPoint.ToString()); NetworkStream ns = client.GetStream(); StreamReader sread = new StreamReader(ns); Console.WriteLine(sread.ReadToEnd()); } } }
|
注意:TcpClient.Client属性就是Socket对象!
(3)UdpClient
UdpClient:提供用户数据报 (UDP) 网络服务。
发送端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Program { static void Main(string[] args) { Thread.Sleep(1000 * 2); UdpClient udpClient = new UdpClient(); udpClient.Connect(IPAddress.Parse("127.0.0.1"), 9999); for (int i = 0; i < 20; i++) { Byte[] data = Encoding.UTF8.GetBytes(i + ":李志伟发送的消息!"); udpClient.Send(data, data.Length); Console.WriteLine("发送消息数:" + i); Thread.Sleep(1000); } udpClient.Close(); Console.Read(); } }
|
接收端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Program { static void Main(string[] args) { UdpClient udpClient = new UdpClient(9999); Console.WriteLine("已监听..."); IPEndPoint RemoteIpEndPoint = null; while (true) { byte[] data = udpClient.Receive(ref RemoteIpEndPoint); string str = Encoding.UTF8.GetString(data); Console.WriteLine("收到消息:" + str); Console.WriteLine("消息来源:" + RemoteIpEndPoint.ToString()+"\n"); } } }
|
(4)SmtpClient
SmtpClient类是用来发送邮件的,它在System.Web.Mail命名空间下。调用SmtpClient类的send(newMessage)方法,其中的参数newMessage是一个MailMessage对象,所以我们在调用send(newMessage)方法前,须实例化MailMessage类,然后对newMessage的属性设值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| class Program { static void Main(string[] args) { SmtpClient smtp = new SmtpClient(); MailMessage mail = new MailMessage("XXX@163.com", "XXXXXX@qq.com"); Attachment attach = new Attachment(@"F:\图片.jpg", MediaTypeNames.Image.Jpeg); attach.ContentId = "pic"; Attachment attach2 = new Attachment(@"F:\图片.rar", "application/x-zip-compressed"); mail.Attachments.Add(attach); mail.Attachments.Add(attach2); mail.Subject = "你好"; mail.SubjectEncoding = Encoding.UTF8; mail.Body = "<img src=\"cid:pic\"/><p>来自李志伟。</p>"; mail.BodyEncoding = Encoding.UTF8; mail.IsBodyHtml = true; smtp.Host = "smtp.163.com"; smtp.UseDefaultCredentials = false; smtp.EnableSsl = true; smtp.Credentials = new NetworkCredential("XXX@163.com", "password"); smtp.DeliveryMethod = SmtpDeliveryMethod.Network; smtp.Send(mail); Console.WriteLine("=============OK============="); Console.Read(); } }
|