C#网络编程

原创 2013年09月24日 20:38:36

C#网络编程

1.网络通信的方式

1)同步方式

同步方式是指当发送方发送一个数据包以后,一直等到接收方响应后,才可以发送下一个数据包。(串行运行)

2)异步方式

异步方式是指发送方发送数据包以后,不等接收方响应,就接着发送下一个数据包。(并行运行)

3)阻塞套接字

阻塞套接字是指在执行此套接字的网络调用时,直到调用成功才返回,否则此套接字就一直阻塞在网络调用上。

4)非阻塞套接字

非阻塞套接字是指在执行此套接字的网络调用时,不管是否执行成功,都立即返回。

2.Dns类、IPAddress类、IPEndPoint类和IPHostEntry

1) Dns

Dns类是一个静态类,它从 Internet 域名系统 (DNS) 检索关于特定主机的信息。在 IPHostEntry 类的实例中返回来自 DNS 查询的主机信息。 如果指定的主机在 DNS 数据库中有多个入口,则 IPHostEntry 包含多个 IP 地址和别名。

常用方法说明

方 法 名 称

说    明

BeginGetHostAddresses

异步返回指定主机的Internet协议(IP)地址

BeginGetHostEntry

已重载。将主机名或IP地址异步解析为IPHostEntry实例

EndGetHostAddresses

结束对DNS信息的异步请求

EndGetHostEntry

结束对DNS信息的异步请求

GetHostAddresses

返回指定主机的Internet协议(IP)地址

GetHostByAddress

已重载。获取IP地址的DNS主机信息

GetHostName

获取本地计算机的主机名

GetType

获取当前实例的类型

GetHostEntry

将主机名或IP地址解析为IPHostEntry实例

2) IPAddress

IPAddress类提供了对IP地址的转换、处理等功能。其Parse方法可将IP地址字符串转换为IPAddress实例。如:

IPAddress ip = IPAddress.Parse(192.168.1.1); 

3) IPEndPoint

IPEndPoint类包含了应用程序连接到主机上的服务所需的IP地址和端口信息。 

4) IPHostEntry

IPHostEntry类将一个域名系统 (DNS) 主机名与一组别名和一组匹配的 IP 地址关联。

常用属性有:AddressList属性和HostName属性。

AddressList属性作用:获取或设置与主机关联的IP地址列表,是一个IPAddress类型的数组,包含了指定主机的所有IP地址;HostName属性则包含了服务器的主机名。

Dns类中,有一个专门获取IPHostEntry对象的方法,通过IPHostEntry对象,可以获取本地或远程主机的相关IP地址。

例子:设计WinForm应用程序用于获取指定主机名的IP地址。 

设计步骤如下:

①新建WinForm项目

新建WinForm项目并命名为“ParseDNS”。

②添加控件并设置属性

Form1的设计视图中将此窗体调整到适当的大小并将 “Text”属性设置为“获取主机IP地址”。从工具箱中拖曳1Button2Label2TextBox控件到窗体中,如图10.1所示布局控件。将label1label2button1Text属性值分别设置为“主机名”、“IP地址:”和“获取”。

③添加命名空间

所要添加的命名空间为“using System.Net;”。

④添加事件及代码

双击“获取”按钮,其事件代码如下所示:

private void button1_Click(object sender, EventArgs e)

{

          textBox2.Text = "";

            try

            {

                IPHostEntry hostInfo = Dns.GetHostEntry(textBox1.Text.Trim());

                textBox2.Text = "主机名:" + Dns.GetHostName() + "\r\n";

                foreach(IPAddress ipadd in hostInfo.AddressList)

                {

                    textBox2.Text += ipadd.ToString() + "\r\n";

                }

            }

            catch(Exception ex)

            {

                MessageBox.Show(ex.Message.ToString());

            }

   }

⑤运行程序

按“Ctrl+F5”组合键运行程序,分别输入“www.baidu.com”和“baidu.com”,单击“获取”按钮,结果如图1和图2所示。

      

                                                        图1                                                                                                                       2

3.System.Net.Socket命名空间

 TCP/IPSocket则提供3种类型的套接字。

该接口允许对较低层协议,如IPICMP直接访问。常用于检验新的协议实现或访问现有服务中配置的新设备。

套接字处理数据两种基本模式:同步套接字和异步套接字。

同步套接字 

其特点是在通过Socket进行连接、接收、发送操作时,客户机或服务器在接收到对方响应前会处于阻塞状态。它适用于数据处理不太多的场合。

异步套接字

在通过Socket进行连接、接收、发送操作时,客户机或服务器不会处于阻塞方式,而是利用callback机制进行连接、接收和发送处理,这样就可以在调用发送或接收的方法后直接返回,并继续执行下面的程序。

IP连接领域有两种通信类型:

面向连接的(connection-oriented)  (TCP)

在面向连接的套接字中,使用TCP协议来建立两个IP地址端点之间的会话。一旦建立了这种连接,就可以在设备之间可靠的传输数据。

无连接的(connectionless)  (UDP)

为了建立面向连接的套接字,服务器和客户端必须分别进行编程。 对于服务器端程序,建立的套接字必须绑定到用于TCP通信的本地IP地址和端口上。

网络流

(stream)是对串行传输的数据的一种抽象表示,底层的设备可以是文件、外部设备、主存、网络套接字等。

C#System.Net.Sockets名称空间中提供了一个专门的NetworkStream类,用于通过网络套接字发送和接收数据。NetworkStream类支持对网络数据的同步或异步访问,它可被视为在数据来源端和接收端之间架设了一个数据通道。

1) Socket

.NET框架的System.NET.Sockets命名空间为需要严密控制网络访问的开发人员提供了WinSock接口的托管实现。

Socket类用于实现Berkeley套接字接口。

Socket类的构造函数

Socket类的构造函数原型如下:

public Socket(

   AddressFamily addressFamily,

   SocketType socketType,

   ProtocolType protocolType

);

构造函数使用3个参数来定义创建的Socket实例。AddressFamily用来指定网络类型;SocketType用来指定套接字类型(即数据连接方式);ProtocolType用来指定网络协议。3个参数均是在命名空间System.Net.Sockets中定义的枚举类型。但它们并不能任意组合,不当的组合反而会导致无效套接字。如对于常规的IP通信网络,AddressFamily只能使用AddressFamily.InterNetwork,此时可用的SocketTypeProtocolType组合如表1所示。

SocketType

ProtocolType

描    述

Stream

Tcp

面向连接套接字

Dgram

Udp

无连接套接字

Raw

Icmp

网际消息控制协议套接字

Raw

Raw

基础传输协议套接字

1

2) TcpClient

TcpClient类为TCP网络服务提供客户端连接,它构建于Socket类之上,以提供较高级别的TCP服务,即提供了通过网络连接、发送和接收数据的简单方法。用于在同步阻止模式下通过网络来连接、发送和接收流数据。另外,通过与NetworkStream对象的关联,使得用户可以通过流操作方式实现对网络连接状态下数据的发送和接收。 通过TcpClient类实现与TCP主机的通信流程如图3所示。

3  TcpClient类与TCP主机的通信流程

1.创建TcpClient实例

TcpClient类有4种构造函数的重载形式,分别对应4种创建实例的方法。

TcpClient( ),这种不带任何参数的构造函数将使用本机默认的IP地址并将使用默认的通信端口号0。当然,如果本机不止一个IP地址时将无法选择使用。

TcpClientAddressFamily),使用指定的地址族初始化TcpClient类的新实例。

TcpClientIPEndPoint),即使用本机IPEndPoint创建TcpClient的实例。其中IPEndPoint将网络端点表示为IP地址和端口号,用于指定在建立远程主机连接时所使用的本地网络接口IP地址和端口号。

TcpClient String, Int32),初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。

因此,在TcpClient的构造函数中,如果没有指定远程主机名和端口号,它只是用来实例化TcpClient,同时实现与本地IP地址和Port端口的绑定。

2.与远程主机建立连接

如果在TcpClient的实例化过程中没有实现与远程主机的连接,则可以通过Connect方法来实现与指定远程主机的连接。Connect方法使用指定的主机名和端口号将客户端连接到远程主机,其使用方法如下。

ConnectIPEndPoint),使用指定的远程网络终结点将客户端连接到远程TCP主机。 

ConnectIPAddress),使用指定的IP地址和端口号将客户端连接到远程TCP主机。 

Connect IPAddress[]Int32),使用指定的IP地址和端口号将客户端连接到远程TCP主机。

ConnectString, Int32),使用指定的主机名和端口号将客户端连接到指定主机上的指定端口。

如下代码段描述了TcpClient实例的创建以及与指定远程主机的连接过程。

m_client = new TcpClient( );

m_client.Connect(m_servername, m_port);

3.利用NetworkStream实例发送和接收数据

TcpClient类创建在Socket之上,提供了更高层次的TCP服务抽象,特别是在网络数据的发送和接收方面,TcpClient使用标准的Stream流处理技术,通过使用NetworkStream实例的读写操作来实现网络数据的接收和发送,因此更加方便直观。但NetworkStream与普通流Stream有所不同,NetworkStream没有当前位置的概念,不支持查找和对数据流的随机访问。

该方法首先通过TcpClient.GetStream来返回NetworkStream实例,进而利用所获取的NetworkStream实例的读写方法WriteRead来发送和接收数据,其实现代码如下所示。 

rs = new StreamReader(m_client.GetStream( ));//获取接收数据的网络流实例

ws = m_client.GetStream( ); //获取发送数据的网络流实例

m_returnData = rs.ReadLine( ); //接收网络数据

Console.WriteLine(m_returnData); 

ws.Write(data, 0, data.Length); //向网络发送数据

4.关闭TCP套接字

在与服务器完成通信后,应该调用Close( )方法释放所有的资源。

    m_client.Close( );

3) TcpListener

TcpClient类实现了客户端编程抽象,因此构建客户端网络应用程序便可以直接使用TcpClient取代Socket,更加方便易用。同样,对于服务器端应用程序的构建,C#提供了TcpListener类。该类也是构建于Socket之上,提供了更高抽象级别的TCP服务,使得程序员能更方便地编写服务器端应用程序。

通常情况下,服务器端应用程序在启动时将首先绑定本地网络接口的IP地址和端口号,然后进入侦听客户请求的状态,以便于客户端应用程序提出显式请求。一旦侦听到有客户端应用程序请求连接侦听端口,服务器端应用将接受请求,并建立一个负责与客户端应用程序通信的信道,即通过创建连接套接字与客户端应用程序建立连接,由连接套接字完成与客户端应用程序的数据传送操作,服务器端应用程序继续侦听更多的客户端连接请求。

TcpListener通过实例创建过程完成与本地网络接口的绑定,并由所创建的实例调用Start方法启动侦听;当侦听到客户端应用程序的连接请求后,根据客户端应用程序的不同请求方式,可以通过AcceptTcpClient方法接受传入的连接请求并创建TcpClient实例以处理请求,或者通过AcceptSocket方法接受传入的连接请求并创建Socket实例以处理请求,并由所创建的TcpClient实例或Socket实例完成与客户端应用程序的网络数据传输。最后,需要使用Stop关闭用于侦听传入连接的Socket,同时也必须关闭从AcceptSocketAcceptTcpClient返回的任何实例,以释放相关资源。其实现流程如右图4所示。

4 TcpListener类与客户机的通信流程

1.创建TcpListener实例

TcpListener类提供了3种构造函数的重载形式来创建TcpListener实例。

TcpListener(port); //指定本机端口 

public TcpListener(IPEndPoint) //指定本机终结点 

public TcpListener(IPAddress,port) //指定本机IP地址及端口 

分别根据指定的侦听端口、IPEndPoint对象(包含了IP地址和端口号)、IPAddress对象和端口号来创建TcpListener实例,并且实现与默认端口或指定IP地址和端口的绑定,如:  

m_host = IPAddress.Parse(m_serverIP);

m_Listener = new TcpListener(m_host, m_port);

2.侦听

创建TcpListener实例后,便可以调用Start方法启动侦听,即该方法将调用TcpListener实例的基础Socket上的Listen方法,开始侦听客户的连接请求,如:

m_Listener.Start( );

3.接收连接请求

当侦听到有客户连接请求时,可以使用AcceptSocketAcceptTcpClient接收任何当前在队列中挂起的连接请求。这两种方法分别返回一个SocketTcpClient实例以接受客户的连接请求,如:

TcpClient m_client = m_Listener.AcceptTcpClient( );

通过返回的SocketTcpClient实例来实现与提出连接请求的客户的单独网络数据传输。

4.收发数据

如果接收连接请求时返回的是Socket实例,则可以用SendReceive方法实现与客户的通信。如果返回的是TcpClient实例,则可以通过对NetworkStream的读写来实现与客户的数据通信。由于服务器可以同时与多个客户建立连接并进行数据通信,因此往往会引入多线程技术,为每个客户的连接建立一个线程,在该线程中实现与客户的数据通信。如下代码所示。

//为每个客户连接创建并启动一个线程

TcpClient m_client = m_Listener.AcceptTcpClient( );

ClientHandle m_handle = new ClientHandle( );

m_handle.ClientSocket = m_client;

Thread m_clientthread = 

                  new Thread(new ThreadStart(m_handle.ResponseClient));

m_clientthread.Start( );

//线程处理代码

public void ResponseClient( )

{

    if (m_clientsocket != null)

    {

      StreamReader rs = new StreamReader(m_clientsocket.GetStream( ));

        NetworkStream ws = m_clientsocket.GetStream( );

        ……

        while (true)

        {

            //接收信息

            m_returnData = rs.ReadLine( );

            ……

            //回送信息

            ws.Write(data, 0, data.Length);

            ……

        }

        m_clientsocket.Close( );

    }

}

5.关闭连接

与客户程序通信完成之后,最后一步是停止侦听套接字,此时可以调用TcpListenerStop方法来实现。

4) UdpClient

TcpClientTcpListener类似,UdpClient也是构建于Socket类之上,提供了更高层次的UDP服务抽象,用于在阻止同步模式下发送和接收无连接 UDP 数据报,使用简单直观。

基于UdpClient的网络应用编程首先需要创建一个UdpClient类实例,接着通过调用其Connect方法连接到远程主机。当然,这两步也可以直接由指定远程主机名和端口号的UdpClient类构造函数完成。然后便可以利用SendReceive方法来发送和接收数据。最后调用Close方法关闭UDP连接,并释放相关资源。其实现流程如图5所示。

图5  基于UdpClient的编程流程

5) NetWorkStream

NetworkStream 类提供在阻止模式下通过 Stream 套接字发送和接收数据的方法。

注:Word文件可到http://download.csdn.net/detail/yuzhongchun/6315293去下载。
版权声明:本文为博主原创文章,未经博主允许不得转载。

C#网络编程,传输数据的3种方式

在使用socket绑定networkstream进行网络传输时,传输的形式都是以字节数组(byte[])进行的。意味着进行读取时都是以字节数组的形式进行。 所以当进行网络通信传输数据时,我们可以使用一...
  • Alexander_Frank
  • Alexander_Frank
  • 2016年05月26日 09:08
  • 4129

C#网络编程系列文章(一)之Socket实现异步TCP服务器

原创性声明 开篇 本人因为对于网络编程的喜爱,经常性的使用c#编写各类服务器(e.g TCP服务器,UDP服务器),但是基本上都是搞着玩,网上也有很多讲c#网络编程的文章,当然我也参考了很多作者写...
  • zhujunxxxxx
  • zhujunxxxxx
  • 2015年03月14日 13:43
  • 18124

C#网络编程系列文章(二)之Socket实现同步TCP服务器

原创性声明 本文作者:小竹zz  本文地址http://blog.csdn.net/zhujunxxxxx/article/details/44258719 转载请注明出处 本文介绍 在上一篇博客中我...
  • zhujunxxxxx
  • zhujunxxxxx
  • 2015年03月14日 17:54
  • 6367

csharp网络编程示例

  • 2012年07月17日 13:38
  • 180KB
  • 下载

C#网络编程TCP通信实例程序简单设计

C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服...
  • CoderJYF
  • CoderJYF
  • 2017年04月20日 10:08
  • 2669

提问与回答 VS2017中C#控制台编程的调试基础示例

我每次从main方法进去,然后就一直走,跳进了循环有时候出不来,也不知道怎么处理,并且根本还不会用红点测试,只知道按F11,求大神赐教,尽快拯救我吧。经常走着走着就忘了代码的逻辑了,还想问一下做断点测...
  • qq_39561376
  • qq_39561376
  • 2017年07月19日 18:34
  • 2349

C# 网络编程之最简单浏览器实现

最近学习C#网络编程的HTTP相关协议编程,HTTP即Hypertext Transfer Protocol的缩写,意为:超文本传输协议。其中与HTTP相关的知识主要包含五个类的知识,分别是:(1)....
  • Eastmount
  • Eastmount
  • 2013年07月26日 08:13
  • 13865

C#网络编程(基本概念和操作) - Part.1

引言 C#网络编程系列文章计划简单地讲述网络编程方面的基础知识,由于本人在这方面功力有限,所以只能提供一些初步的入门知识,希望能对刚开始学习的朋友提供一些帮助。如果想要更加深入的内容,可以参考相关书...
  • abc456456456456
  • abc456456456456
  • 2014年03月31日 11:17
  • 1021

C#网络编程TCP通信实例程序简单设计

C#网络编程TCP通信实例程序简单设计 采用自带 TcpClient和TcpListener设计一个Tcp通信的例子 只实现了TCP通信 通信程序截图: 压力测试服务端截图: 俩个客户端链接服...
  • CoderJYF
  • CoderJYF
  • 2017年04月20日 10:08
  • 2669

C#网络编程,传输数据的3种方式

在使用socket绑定networkstream进行网络传输时,传输的形式都是以字节数组(byte[])进行的。意味着进行读取时都是以字节数组的形式进行。 所以当进行网络通信传输数据时,我们可以使用一...
  • Alexander_Frank
  • Alexander_Frank
  • 2016年05月26日 09:08
  • 4129
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#网络编程
举报原因:
原因补充:

(最多只允许输入30个字)