Visual C#网络编程之TCP

2016-02-19 16:55 8 1 收藏

下面图老师小编跟大家分享一个简单易学的Visual C#网络编程之TCP教程,get新技能是需要行动的,喜欢的朋友赶紧收藏起来学习下吧!

【 tulaoshi.com - 编程语言 】

  前一篇《Visual C#.Net网络程序开发之Socket》中说到:支持Http、Tcp和Udp的类组成了TCP/IP三层模型(请求响应层、应用协议层、传输层)的中间层-应用协议层,该层的类比位于最底层的Socket类提供了更高层次的抽象,它们封装 TCP 和 UDP 套接字的创建,不需要处理连接的细节,这使得我们在编写套接字级别的协议时,可以更多地尝试使用 TCPClient 、 UDPClient和TcpListener,而不是直接向 Socket 中写。它们之间的这种层次关系示意如下:

  可见,TcpClient 类基于 Socket 类构建,这是它能够以更高的抽象程度提供 TCP 服务的基础。正因为这样,许多应用层上的通讯协议,比如FTP(File Transfers Protocol)文件传输协议、HTTP(Hypertext Transfers Protocol)超文本传输协议等都直接创建在TcpClient等类之上。

  TCPClient 类使用 TCP 从 Internet 资源请求数据。TCP 协议建立与远程终结点的连接,然后使用此连接发送和接收数据包。TCP 负责确保将数据包发送到终结点并在数据包到达时以正确的顺序对其进行组合。

  从名字上就可以看出,TcpClient类专为客户端设计,它为 TCP 网络服务提供客户端连接。TcpClient 提供了通过网络连接、发送和接收数据的简单方法。

  若要建立 TCP 连接,必须知道承载所需服务的网络设备的地址(IPAddress)以及该服务用于通讯的 TCP 端口 (Port)。Internet 分配号码机构 (Internet Assigned Numbers Authority, IANA) 定义公共服务的端口号(你可以访问 http://www.iana.org/assignments/port-numbers获得这方面更详细的资料)。IANA 列表中所没有的服务可使用 1,024 到 65,535 这一范围中的端口号。要创建这种连接,你可以选用TcpClient类的三种构造函数之一:

  1、public TcpClient()当使用这种不带任何参数的构造函数时,将使用本机默认的ip地址并将使用默认的通信端口号0。这样情况下,如果本机不止一个ip地址,将无法选择使用。以下语句示例了如何使用默认构造函数来创建新的 TcpClient:

  TcpClient tcpClientC = new TcpClient();

  2、public TcpClient(IPEndPoint)使用本机IPEndPoint创建TcpClient的实例对象。上一篇介绍过了,IPEndPoint将网络端点表示为IP地址和端口号,在这里它用于指定在建立远程主机连接时所使用的本地网络接口(IP 地址)和端口号,这个构造方法为使用本机IPAddress和Port提供了选择余地。下面的语句示例了如何使用本地终结点创建 TcpClient 类的实例:

  

IPHostEntry ipInfo=Dns.GetHostByName("www.tuha.net");//主机信息IPAddressList[] ipList=ipInfo.AddressList;//IP地址数组IPAddress ip=ipList[0];//多IP地址时一般用第一个IPEndPoint ipEP=new IPEndPoint(ip,4088);//得到网络终结点try{TcpClient tcpClientA = new TcpClient(ipLocalEndPoint);}catch (Exception e ) {Console.WriteLine(e.ToString());} 

  到这里,你可能会感到困惑,客户端要和服务端创建连接,所指定的IP地址及通信端口号应该是远程服务器的呀!事实上的确如此,使用以上两种构造函数,你所实现的只是TcpClient实例对象与IP地址和Port端口的绑定,要完成连接,你还需要显式指定与远程主机的连接,这可以通过TcpClient类的Connect方法来实现, Connet方法使用指定的主机名和端口号将客户端连接到 远程主机:

  1)、public void Connect(IPEndPoint); 使用指定的远程网络终结点将客户端连接到远程 TCP 主机。

  public void Connect(IPAddress, int); 使用指定的 IP 地址和端口号将客户端连接到 TCP 主机。

  public void Connect(string, int); 将客户端连接到指定主机上的指定端口。

  需要指出的是,Connect方法的所有重载形式中的参数IPEndPoint网络终结点、IPAddress以及表现为string的Dns主机名和int指出的Port端口均指的是远程服务器。

  以下示例语句使用主机默认IP和Port端口号0与远程主机建立连接:

  

TcpClient tcpClient = new TcpClient();//创建TcpClient对象实例try{tcpClient.Connect("www.contoso.com",11002);//建立连接}catch (Exception e ){Console.WriteLine(e.ToString());}

  3、public TcpClient(string, int);初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。与前两个构造函数不一样,这个构造函数将自动建立连接,你不再需要额外调用Connect方法,其中string类型的参数表示远程主机的Dns名,如:www.tuha.net。

  以下示例语句调用这一方法实现与指定主机名和端口号的主机相连:

  

try{TcpClient tcpClientB = new TcpClient("www.tuha.net", 4088);}catch (Exception e ) {Console.WriteLine(e.ToString());} 

  前面我们说,TcpClient类创建在Socket之上,在Tcp服务方面提供了更高层次的抽象,体现在网络数据的发送和接受方面,是TcpClient使用标准的Stream流处理技术,使得它读写数据更加方便直观,同时,.Net框架负责提供更丰富的结构来处理流,贯穿于整个.Net框架中的流具有更广泛的兼容性,构建在更一般化的流操作上的通用方法使我们不再需要困惑于文件的实际内容(HTML、XML 或其他任何内容),应用程序都将使用一致的方法(Stream.Write、Stream.Read) 发送和接收数据。另外,流在数据从 Internet 下载的过程中提供对数据的即时访问,可以在部分数据到达时立即开始处理,而不需要等待应用程序下载完整个数据集。.Net中通过NetworkStream类实现了这些处理技术。

  NetworkStream 类包含在.Net框架的System.Net.Sockets 命名空间里,该类专门提供用于网络访问的基础数据流。NetworkStream 实现通过网络套接字发送和接收数据的标准.Net 框架流机制。NetworkStream 支持对网络数据流的同步和异步访问。NetworkStream 从 Stream 继承,后者提供了一组丰富的用于方便网络通讯的方法和属性。

  同其它继承自抽象基类Stream的所有流一样,NetworkStream网络流也可以被视为一个数据通道,架设在数据

  .Net中的TCPListener 用于监视TCP 端口上的传入请求,通过绑定本机IP地址和相应端口(这两者应与客户端的请求一致)创建TcpListener对象实例,并由Start方法启动侦听;当TcpListener侦听到用户端的连接后,视客户端的不同请求方式,通过AcceptTcpClient 方法接受传入的连接请求并创建 TcpClient 以处理请求,或者通过AcceptSocket 方法接受传入的连接请求并创建 Socket 以处理请求。最后,你需要使用 Stop 关闭用于侦听传入连接的 Socket,你必须也关闭从 AcceptSocket 或 AcceptTcpClient 返回的任何实例。这个过程详细解说如下:

  首先,创建TcpListener对象实例,这通过TcpListener类的构造方法来实现:

  

public TcpListener(port);//指定本机端口public TcpListener(IPEndPoint)//指定本机终结点public TcpListener(IPAddress,port)//指定本机IP地址及端口 

  以上方法中的参数在前面多次提到,这里不再细述,唯一需要提醒的是,这些参数均针对服务端主机。下面的示例演示创建 TcpListener 类的实例:

  

IPHostEntry ipInfo=Dns.Resolve("127.0.0.1");//主机信息IPAddressList[] ipList=ipInfo.IPAddressList;//IP数组IPAddress ip=ipList[0];//IPtry{TcpListener tcpListener = new TcpListener(ipAddress, 4088);//创建TcpListener对象实例以侦听用户端连接}catch ( Exception e){MessageBox.Show("TcpListener错误:"+e.Message);} 

  随后,你需要调用Start方法启动侦听:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  public void Start();

  其次,当侦听到有用户端连接时,需要接受挂起的连接请求,这通过调用以下两方法之一来完成连接:

  

public Socket AcceptSocket();public TcpClient AcceptTcpClient(); 

  前一个方法返回代表客户端的Socket对象,随后可以通过Socket 类的 Send 和 Receive 方法与远程计算机通讯;后一个方法返回代表客户端的TcpClient对象,随后使用上面介绍的 TcpClient.GetStream 方法获取 TcpClient 的基础网络流 NetworkStream,并使用流读写Read/Write方法与远程计算机通讯。

  最后,请记住关闭侦听器:public void Stop();

  同时关闭其他连接实例:public void Close();

  下面的示例完整体现了上面的过程:

  

bool done = false;TcpListener listener = new TcpListener(13);// 创建TcpListener对象实例(13号端口提供时间服务)listener.Start();//启动侦听while (!done) {//进入无限循环以侦听用户连接TcpClient client = listener.AcceptTcpClient();//侦听到连接后创建客户端连接TcpClientNetworkStream ns = client.GetStream();//得到网络传输流byte[] byteTime = Encoding.ASCII.GetBytes(DateTime.Now.ToString());//预发送的内容(此为服务端时间)转换为字节数组以便写入流try {ns.Write(byteTime, 0, byteTime.Length);//写入流ns.Close();//关闭流client.Close();//关闭客户端连接}catch (Exception e) {MessageBox.Show("流错误:"+e.Message)}

  综合运用上面的知识,下面的实例实现了简单的网络通讯-双机互连,针对客户端和服务端分别编制了应用程序。客户端创建到服务端的连接,向远程主机发送连接请求连接信号,并发送交谈内容;远程主机端接收来自客户的连接,向客户端发回确认连接的信号,同时接收并显示客户端的交谈内容。在这个基础上,发挥你的创造力,你完全可以开发出一个基于程序语言(C#)级的聊天室!

  客户端主要源代码:

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  

public void SendMeg()//发送信息{try{int port=Int32.Parse(textBox3.Text.ToString());//远程主机端口try{tcpClient=new TcpClient(textBox1.Text,port);//创建TcpClient对象实例 }catch(Exception le){MessageBox.Show("TcpClient Error:"+le.Message);}string strDateLine=DateTime.Now.ToShortDateString()+" "+DateTime.Now.ToLongTimeString();//得到发送时客户端时间netStream=tcpClient.GetStream();//得到网络流sw=new StreamWriter(netStream);//创建TextWriter,向流中写字符string words=textBox4.Text;//待发送的话string content=strDateLine+words;//待发送内容sw.Write(content);//写入流sw.Close();//关闭流写入器netStream.Close();//关闭网络流tcpClient.Close();//关闭客户端连接}catch(Exception ex){MessageBox.Show("Sending Message Failed!"+ex.Message);}textBox4.Text="";//清空} 

  服务器端主要源代码:

  

public void StartListen()//侦听特定端口的用户请求{//ReceiveMeg();isLinked=false; //连接标志try{int port=Int32.Parse(textBox1.Text.ToString());//本地待侦听端口serverListener=new TcpListener(port);//创建TcpListener对象实例serverListener.Start(); //启动侦听}catch(Exception ex){MessageBox.Show("Can‘t Start Server"+ex.Message);return;}isLinked=true;while(true)//进入无限循环等待用户端连接{try{tcpClient=serverListener.AcceptTcpClient();//创建客户端连接对象netStream=tcpClient.GetStream();//得到网络流sr=new StreamReader(netStream);//流读写器}catch(Exception re){MessageBox.Show(re.Message);}string buffer="";string received="";received+=sr.ReadLine();//读流中一行while(received.Length!=0){buffer+=received;buffer+="rn";//received="";received=sr.ReadLine();}listBox1.Items.Add(buffer);//显示//关闭sr.Close();netStream.Close();tcpClient.Close();}} 

来源:http://www.tulaoshi.com/n/20160219/1613580.html

延伸阅读
有时,我们需在我们的程序中模拟鼠标的移动、点击等动作。比如,一个再现用户操作的宏,或者一个演示操作方法的Demo程序。那么,我们在.Net中如何实现呢? .Net并没有提供改变鼠标指针位置、模拟点击操作的函数;但是Windows API提供了。其中一个是: [DllImport("user32.dll")]static extern bool SetCursorPos(int ...
C#(发音为See Sharp)是简单、现代、面向对象和类型安全的编程语言。C#起源于C语言家族,因此,C,C++和Java的程序员很快就能熟悉它。C#已经获得了ECMA International和ISO/IEC的国际标准认证,它们分别是ECMA-334标准和ISO/IEC 23270标准。Microsoft用于.NET框架的C#编译器就是根据这两个标准实现的。 C#是面向对象的语言,但C#进一...
本文就来着重探讨一下 Visual C# 数据库基本编程,即:如何浏览记录、修改记录、删除记录和插入记录。针对 数据库 编程始终是程序设计语言的一个重要方面的内容,也是一个难点。数据库编程的内容十分丰富,但最为基本编程的也就是那么几点,譬如:连接数据库、得到需要的数据和针对数据记录的浏览、删除、修改、插入等操作。其中又以后面针...
本文向大家介绍Windows Sockets的一些关于用C#实现的原始套接字(Raw Socket)的编程,以及在此基础上实现的网络封包监视技术。同Winsock1相比,Winsock2最明显的就是支持了Raw Socket套接字类型,使用Raw Socket,可把网卡设置成混杂模式,在这种模式下,我们可以收到网络上的IP包,当然包括目的不是本机的IP包,通过原始套接字,我们也可以...
ICMP就是所谓的Internet控制报文协议(Internet Control Message Protocol),在网络中,一般用它来传递差错报文以及其他应注意的信息。ICMP一般被认为是和IP协议同一层的协议,IMCP报文通常被IP层或者更高层的协议(如:TCP或者UDP)使用,ICMP对于互联网以及其他基于IP协议的网络的正常运行起着非常重要的作用。有许多重要的网络程序都是...

经验教程

192

收藏

95
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部