.Net的网络编程

IT商界

  了解.Net网络编程

  .Net的发布本身就是为简化网络软件编程而发布的,在.Net中我们可以很容易地使用如TCP/IP、UDP、HTTP之类的网络协议进行软件的开发。但是这些协议本身是建立在Socket之上的。而且在.Net中关于TCP/IP、UDP、HTTP这些协议的类都是从Socket类继承下来的,所以读者只要掌握了.Net中的Socket类的编程就可以很快地掌握TCP/IP、UDP、HTTP方面的编程技巧了。

  Socket是套接字的英文名称,主要作用是用于网络编程和通信,在以前VB6时要想使用Socket进行程序开发最麻烦的是要自己声明Socket动态库中的相关函数,而这些函数的参数多不说,还是用c语言编写的,要让它门在VB中运行最头痛的就是要进行函数参数的转换。经常是为了测试一个参数的转换是否正确而花上大半天的功夫。

  不过现在不同了,有了.Net,它的System.Net.Sockets命名空间包含Windows套接字接口的托管实现。而System.Net命名空间中的所有其他网络访问类都建立在该套接字实现的基础之上,也就是说使用System.Net.Sockets和System.Net命名空间中类可以完成通过socket动态库中的几乎全部功能,但是又避免了参数转化的麻烦。

  本文我们就通过两个简单的例子来看看如何实现Socket的编程。

  例一 聊天程序

  字符串是网络传输的根本,就算是文件的传输,在网络中都被转化为字符。所以我们就从最简单的聊天程序开始。

  注意:本文中的程序需要用户编写两个实例才可以完成,它们分别是发送端和接受端。

  '发送端代码

  Public Class Form1

  Inherits System.Windows.Forms.Form

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

  Dim bytes(1024) As Byte'声明字节数组用来保存要发送的数据

  Dim sender1 As New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream,Net.Sockets.ProtocolType.Tcp)'初始化socket

  Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(TextBox1.Text)'对发送的数据进行编码,将它转化为二进制格式

  '***************************

  '指定IP和端口

  Dim ipHostInfo As System.Net.IPHostEntry = System.Net.Dns.Resolve("d")

  Dim ipAddress As System.Net.IPAddress = ipHostInfo.AddressList(0)

  Dim ipe As New System.Net.IPEndPoint(ipAddress, 11000)

  '**********************

  sender1.Connect(ipe)'建立连接

  Dim bytesSent As Integer = sender1.Send(msg)'发送数据

  '(((((((((

  '关闭socket

  sender1.Shutdown(Net.Sockets.SocketShutdown.Both)

  sender1.Close()

  ')))))))

  End Sub

  End Class

  程序说明:在使用套接字通信之前,必须使用协议和网络地址信息初始化套接字。Socket类的构造函数具有指定套接字用来建立连接的地址族、套接字类型和协议类型的参数。然后指定要发送到目标机器的IP地址和端口号。再将要发送数据的字节数组传递到Socket类的数据发送方法Send方法。最后关闭Socket终止发送。

  '接收端代码

  Public Class Form1

  Inherits System.Windows.Forms.Form

  Dim listener As New System.Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)'初始Socket

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  '指定IP和端口

  Dim ipHostInfo As System.Net.IPHostEntry = System.Net.Dns.Resolve(System.Net.Dns.GetHostName)  

  Dim ipAddress As System.Net.IPAddress = ipHostInfo.AddressList(0)

  Dim localEndPoint As New System.Net.IPEndPoint(ipAddress, 11000)

  listener.Bind(localEndPoint)

  listener.Listen(10)

  End Sub

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

  Dim bytes() As Byte = New [Byte](1024) {}

  Dim handler As System.Net.Sockets.Socket = listener.Accept()'建立连接请求

  Dim data As String = Nothing

  bytes = New Byte(1024) {}'声明数组用来保存接收到的数据

  Dim bytesRec As Integer = handler.Receive(bytes)'接收数据

  data += System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec)'进行编码转换,将接收到的二进制数据转化为字符串进行显示

  TextBox1.Text = data

  Dim msg As Byte() = System.Text.Encoding.ASCII.GetBytes(data)

  handler.Shutdown(Net.Sockets.SocketShutdown.Both)

  handler.Close()

  End Sub

  End Class

  程序说明:和发送端一样先需要初始化套接字,指定接收方IP和端口号(必须与发送方相同),通过Listen方法监听指定的接收方IP和端口号,申请连接,使用Receive接收数据,再将数据传给字节数组,最后关闭Socket。

  说明:本程序未进行异常处理,所以不可以连续点“接收”键,其原因是让读者快速掌握.Net中的Socket编程基础(如要进行异常处理,请加入try块,详情见MSDN)。由于本代码中的数据编码使用的是英文编码,所以不支持中文字体(通过对编码的修改可以发送中文,见MSDN)。本文的目的不是教各位编写聊天程序,所以在看本文时请从Socket方面进行思考。本程序在局域网和Internet中测试时都通过了,如果是想在Internet中使用本程序,需要将文中的接收和发送方的Dim ipe As New System.Net.IPEndPoint(ipAddress, 11000)语句中的ipaddress修改为真的IP地址并分别将发送和接收安装于不同IP地址的计算机上。

  例二 实现文件传输

  在这个简单的例子中我们将通过Socket来实现文件的网络传输和接收功能。要实现这两个功能我们需要通过vs.Net建立两个实例来完成。一个发送端,一个接收端。由于文中已经给出了详细的注释这里就不罗嗦了。

  '发送端

  Public Class Form1

  Inherits System.Windows.Forms.Form

  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

  Dim sendsocket As New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)'实例化socket

  Dim ipendpiont As New Net.IPEndPo

  int(Net.IPAddress.Parse("192.168.0.1"), 8888)'指定IP地址和端口

  Dim fs As New IO.FileStream("c:\p.doc", IO.FileMode.OpenOrCreate, IO.FileAccess.Read)'将要传输的文件进行流处理

  Dim fssize(fs.Length - 1) As Byte'设置要传输文件的大小

  Dim strread As New IO.BinaryReader(fs)'流处理要传输的文件

  strread.Read(fssize, 0, fssize.Length - 1)'将流处理后要发送读入到fssize中

  sendsocket.Connect(ipendpiont)'连接远程计算机

  sendsocket.Send(fssize)'发送文件

  Label1.Text = fs.Length()'显示文件的大小

  fs.Close()'关闭流

  sendsocket.Shutdown(Net.Sockets.SocketShutdown.Send)'关闭发送连接

  sendsocket.Close()'关闭本机Socket

  End Sub

  End Class

  程序说明:对于文件的发送来说首先我们要对文件进行流处理,以便将它变成字节来进行传输。在这里我们仍然使用Send来进行数据的传输。

  '接收端

  Public Class Form1

  Inherits System.Windows.Forms.Form

  Dim receivesocket As New Net.Sockets.Socket(Net.Sockets.AddressFamily.InterNetwork, Net.Sockets.SocketType.Stream, Net.Sockets.ProtocolType.Tcp)'实例化socket

  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

  Dim hostipendpiont As New Net.IPEndPoint(Net.IPAddress.Parse("192.168.0.1"), 8888)'指定IP和端口

  receivesocket.Bind(hostipendpiont)'建立远程计算机的socket

  receivesocket.Listen(2)'监听socket

  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

  Dim recfs As New IO.FileStream("p.doc", IO.FileMode.OpenOrCreate)'接收数据并将它保存到一个新的文件中

  Dim recbyte(229888) As Byte

  Dim hostsocket As Net.Sockets.Socket = receivesocket.Accept()'同意和发送端计算机建立连接

  Dim newfilestr As New IO.BinaryWriter(recfs)'将接收到的数据写入字节数组中

  hostsocket.Receive(recbyte)'开始接收

  newfilestr.Write(recbyte, 0, recbyte.Length - 1)

  recfs.Close()'关闭流

  hostsocket.Shutdown(Net.Sockets.SocketShutdown.Receive)

  hostsocket.Close()

  End Sub

  End Class

  程序说明:在接收端先在Form1_Load中实例化Socket后并指定IP和端口然后建立两台计算机的连接。然后在Button1_Click中指定接收文件的大小,并使用Accept表示同意进行连接,然后使用Receive接收数据,并使用流的方式将接收的数据写入到文件。最后将流和Socket关闭。

  总结

  本文通过两个例子揭示了在.Net中如何进行Socket编程的基本方法,不管是传输文字还是传输文件,其代码都大同小异。只要你熟悉了Socket的编程方法,那么在以后学习TCP/IP、UDP、HTTP等编程时就会轻车熟路。