TCPIP网络编程

TCPIP网络编程
TCPIP网络编程

TCP/IP网络编程

一、TCP/IP简介

TCP/IP是一种网络通信协议,优点在于规范了网络上的所有通信设备,尤其一个主机与另一个主机之间的数据往来格式以及传送方式。TCP/IP是Internet的基础协议,也是一种电脑数据打包和寻址的标准方式。

在数据传送中,可以形象地理解为有两个信封,TCP和IP就像是信封,要传递的信息被划分成若干段,每一段塞入一个TCP信封,并在该信封面上记录有分段号的信息,再将TCP信封塞入IP大信封,发送上网。而在接收端,一个TCP软件包负责收集信封,抽出数据,把这些数据按发送前的顺序还原,并加以校验,若发现差错,根据协议,接收端会发出“重发该数据”的请求。因此,TCP/IP在Internet中几乎可以无差错地传送数据。

在TCP协议中,规定了如何将信息正确无误地送抵目的段,TCP模块先将信息切割打包成一块块数据包,根据记录及追踪送出的数据包,可以得知哪些数据包已经到达目的端主机。而对于那些没有到达目的端主机的资料包,根据反馈信息就必须再送一次,直到对方确定收到为止。这些数据包将会在网络中路由前进,经过各种不同类型的网络及主机才能到达目的端。当数据包在网络中穿梭时,互联网层的IP协议会帮助我们把这些包发送到它们的目的地。

在IP协议中,当数据包经过不同类型的网络时,由于每一种网络所能传输的单元大小是不同的,根据连接网络内的不同主机内的IP模块,需要把资料包重整成各种规格的数据块,然后才能适应新的网络环境进行传输。此外,IP也定义了在网络上每一台主机的地址格式,有了这些可唯一确认每一台主机的地址,每一块包含IP地址的数据块才能够正确地抵达目的端主机。

到达目的端之后,目的端主机的IP模块会设法将所有的数据块组合起来成为数据包,TCP模块再将数据包组合成信息,并根据需要要求源端重新发送丢失的数据包。目的端主机上的TCP模块确定数据包已经组合成为完整无缺的信息之后,再通知源端主机的TCP模块,任务完成。最后,目的端主机上再将所接收到的文件以与源文件同样的格式展现给用户。

从这一个过程中看出,IP协议是TCP/IP的心脏,IP协议能提供基本的封包传送服务,而TCP协议则规范了在网络里不同主机之间的建立连接的方式,这两个协议的相互协作,是TCP/IP网络赖以建立的基础。

IP地址是网络上标识主机的编号。而所谓的端口号则标识的是哪一

个具体的应用程序。打个比方来讲,IP地址是构建在网络上不同服务机构所在大楼的“门牌号码”,而端口号,则是具体服务机构里提供服务部门的“房间号”。

二、C#中网络编程相关类

2.1. IPAddress

IPAddress的对象用于表示一个少地址。IPAddress类的默认构造函数

如下所示:

Public IPAddress(long address)

以上构造函数取一个长值,并把它转换成lP地址。PAddres类中有如

下表所示的方法来创建和操作IP地址。

用以下两句代码来获取本地IP地址:

IPHostEntry here=Dns.GetHostByName(Dns.GetHostName());

IPAddress localaddress=here.AddressList[0];

2.2 DNS类

DNS(Domain Name System)是一种分层次的、基于域的命名方案,并且用一个分布式数据库系统来实现此命名方案。

DNS的主要用途是将主机名和电子邮件目标地址映射成IP地址。简单地说,为了将

一个名字映射成IP地址,应用程序先调用一个解析器的库过程,并将该名字作为参数传递给此过程;然后,解析器向本地的DNS服务器发送一个UDP分组;之后,本地DNS服务器查找该名字,并且将找到的IP地址返回给解析器;解析器再将IP地址返回给调用方。得到IP地址之后,应用程序就可以与目标机器建立一个TCP连接,互相传递信息。

DNS类是一个静态类,它从Internet域名系统(DNS)检索关于特定主机的信息。DNS类的公共方法如下表所示。

2.3 IPEndPoint类

从功能上看,IPEndPoint类是将网络端点表示为IP地址和端口号,它的对象表示指定的IP地址和端口组合。

IPEndPoint类包含应用程序连接到主机上的服务所需的主机和本地或远程端口信息。通过组合服务的主机IP地址和端口号,IPEndPoint类形成到服务的连接点。有两个创造IPEndPoint实例的构造函数: public IPEndPoint (long address, int port)

public IPEndPoint (IPAddress address, int port) 两个构造函数都使用两个参数:一个IP地址,用长值表示或者用一个IPAddress对象表示:一个整数端口号。一般经常用第二种构造函数。其对象的各种公共方法如下表所示。

IPEndPoint类包含三个可以设置的或者从实例中获取的属性:

2.4 Socket类

Socket类为网络通信程序提供了一套丰富的方法和属性。应用程序可以通过TCPClient、TCPListener和UDPClient类使川传输控制协议(TCP)和用户数据报文协议(UDP)服务。这些协议议类建立在

https://www.360docs.net/doc/a210806125.html,.Sockets.Socket类的基础之上,负责数据传送的细节。

这些协议类使用Socket类的同步方法提供对网络服务的简单直接的访问,没有维护状态信息的系统开销,也不需要了解协议特定的套接字的设置细节。要使用异步Socket方法,可以使用NetworkStream类提供的异步方法。要访问不是由协议类公开的Socket类的功能,必须使用Socket 类。

三、套接字

简单地说,就是不同的计算机之间为了满足各自进程间通信的需要所架设的一条数据

通道,是一个通信链的句柄。套接字出现的动机是:应用层通过传输层进行数据通信时,TCP和UDP会遇到同时为多个应用程序进程提供并发服务的问题。多个TCP连接或多个应用程序进程可能需要通过同一个TCP协议端口传输数据。为了区别不同的应用程序进程和连接,许多计算机操作系统为应用程序与TCP/IP协议交互提供了称为套接字(Socket)的接口,区分不同应用程序进程间的网络通信和连接。

生成套接字主要有3个参数:通信的目的IP地址、使用的传输层协

(TCP或UDP)和使用的端口号。通过将这3个参数结合起来,与Socket绑

定,应用层就可以和传输层通过套接字接口,区分来自不同应用程序进

程或网络连按的通信,实现数据传输的并发服务。

然而,以上所罗列的这些方法仅仅只能满足一台计算机的通信任务,

要实现网间的进

程通信就要依靠套接字来提供相应的服务。

3.1 套接字的类型和常用属性

以下是C#中的套接字类的原型:

https://www.360docs.net/doc/a210806125.html,.Sockets.Socket

public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

其中SocketType与ProtocolType要对应,其对应关系如下:

3.1.1 Socket类常用属性

(1)Blocking属性

它表示套接字是否处于阻塞的状态,如果这个套接字当前处于阻塞

状态,并且调用了这个套接字里的一个需要花一定时间来执行的方法,

那么应用程序将阻塞,直至请求的操作完成后才解除阻塞。如果希望应

用程序在请求套接字的操作尚未完成的情况下也可以继续执行,有必要

将Blocking属性设为false。

(2)Connected属性

这个属性可以反映出操作的连接状态,Connected属性获取截止到最

后的I/O操作时Socket的连接状态。从取值的情况来看,当它返回false

时,表明Socket要么未连接,要么已经断开连接。

(3)LocalEndPoint属性

这个属性用来表述本机的终结点,即IP地址与端口号的组合。它是EndPoint类型的,在使用过程中,可以按需要把它转换为IPEndPoint类

型。从应用角度来分析,LocalEndPoint属性通常是在调用Bind方法之后设置的。如果允许系统分配套接字的本地IP地址和端口号,则将在第一次I/O操作之后设置LocalEndPoint属性。

(4)RemoteEndPoint属性

如果使用面向连接的协议(TCP),则RemoteEndPoint属性将获取包含Socket连接到的远程IP地址和端口号EndPoint。而如果当前使用的是无连接的协议(UDP),则RemoteEndPoint包含将要Socket通信的默认远程IP地址和端口号。RemoteEndPoint是在调用Accept或Connect之后设置的。

3.1.2 Socket类常用方法

(1)Socket(AddressFamily af, SocketType st, ProtocolType pt)创建套接字,并且返回新建套接字句柄st。对于客户端来说,也是本地创建套接字。

(2)bind(IPEndPoint iep)

对于服务器方的程序来说,建立的套接字必须要绑定到本地计算机的IP地址和端口上。

(3)listen(int backlog)

这个方法用于等待客户端发出连接的请求,待其执行完则说明服务器方已经准备好接受来自客户端的连接。其中的backlog参数是指用户的连接数,超过连接数的其他客户不得与服务器方进一步通信。

(4)accept()

它的功能是,当有新客户进行连接时,返回一个新的套接字句柄。当程序执行到该方法时会处于阻塞状态,直到有新的客户机请求连接,accept()方法会返回包含客户端信息的套接字句柄。

(5)connect(IPEndPoint iep)

此方法为客户机独有,它负责把自己新创建的套接字与本地地址相绑定,与bind()方法相对应。

(6)Send()/Receive()

这两个方法在完成了客户端的连接后,就可以通过它们进行数据传送了。

(7)ShutDown()

在通信完成以后负责把连接释放,并关闭Socket对象。

3.2 建立面向连接的套接字

面向连接的套接字一般是针一对TCP协议来建立两端之间的通信。只要建立了连接,就可以在设备之间进行可靠的数据传送。

要通过互联网进行通信,至少需要一对套接字,一个运行于客户机端,称之为ClientSocket;另一个运行于服务器端,称之为ServerSocket。

根据连接启动的方式以及本地套接字要连接的目标,套接字之间的连接过程可以分为三个步骤:服务器监听,客户端请求,连接确认。

服务器监听:是服务器端套接字并不定位具体的客户端套接

字,而是处于等待连接的状态,实时监控网络状态。

客户端请求:是指由客户端的套接字提出连接请求,要连接

的目标是服务器端的套接字。为此,客户端的套接字必须首

先描述它要连接的服务器的套接字,指出服务器端套接字的

地址和端口号,然后就向服务器端套接字提出连接请求,服

务器在接收到请求后给予回复。

连接确认:是指当服务器端套接字监听到或者说接收到客户

端套接字的连接请求,它就响应客户端套接字的请求。建立

一个新的线程,把服务器端套接字的描述发给客户端。一旦

客户端确认了此描述,连接就建立好了。而服务器端套按字

继续处于监听状态,继续接收其他客户端套接字的连接

请求。

下图是基于客户机/服务器结构的面向连接的套接字工作流程图。其说明了套接字在工作流程中的如下重要步骤:

(1)通过套接字的构造函数方法创建套接字对象并与本地的终结点进行绑定。

(2)在端口上使用listen方法侦听是否有连接请求,如果侦听到连接请求则开始准备连接。

(3)accept方法则会从客户端接入连接,建立连接后,accept方法会返回一个新的套接字,如果没有连接请求则进入循环阻塞,直到收到连接请求后才开始进行连接。

从客户端的角度来说,它调用connect方法尝试与服务器建立连接。一旦这种连接建立以后,双方就可以通过套接字进行通信。而send和receive方法就会负贡对数据的传送和接收。

(4)待数据传送结束后,双方使用shutdown方法释放连接,接着调用close()关闭套接字。

3.3 建立面向无连接的套接字

面向无连接的套接字并不需要面向连接的方式那样发送连接信息,通常,UDP协议就是面向无连接的套接字。

面向无连接的套接字工作流程如下图所示,相对来说,它与有连接的方式有如下几点区别:

(1)都是采用了bind()方法做了对本地地址和套接字的绑定。这里强调下,只有正确地完成了绑定,才能够进行下面的数据传送。

(2)由于是面向无连接的方式,所以不需要像之前那样建立连接,可以在绑定完成之后即开始传输数据。

(3)无连接方式采用SendTo方法和ReceiveFrom方法,这一点要和

面向连接方式区分开来,因为无连接方式不进行连接。所以一定要指定口标主机的地址。

(4)最后只要释放连接,关闭套接字即可。

相关主题
相关文档
最新文档