一. Socket编程基础
1.  Socket
网络套接字(Socket)是基于TCP/IP协议的程序实现协议。实际上,我们所有的网络编
程都是基于Socket而实现的。
Socket在UNIX和Windows甚至Linux上都得到很好的支持(而且此三种操作系统之间的数
据通信也是通过Socket编程来实现的),所以,我们通常把基于TCP/IP协议的网络编程
称之为Socket的程序实现。
1) Socket
Socket的中文翻译是套接字。它是网络通信的基本构件。
Socket是可以被命名和寻址的通信端口。
使用中的每个Socket都有其对应的类型和一个与之相连的进程(线程)
2) TCP和UDP
面向连接的操作使用TCP协议,这个模式下的Socket必须在发送数据之前与目的地的S
ocket取得一个连接,一旦连接建立了,Sockets就可以通过一个数据流接口,发送或者
接收信息。所有的发送的信息都会在另一端以同样的顺序被接收。
面向连接的TCP协议比无连接的UDP协议执行的效率更低,但是数据的安全性、可靠性得
到保障。
无连接的操作使用UDP数据报协议。数据报,顾名思义,就像是报纸的投递一样。是一
个单向的数据发送操作。
一个数据报是一个独立的单元,它包含了所有的这次消息发送的所有信息。有目的地址
和要发送的内容,这个模式下的Socket不需要与一个目的Socket建立连接,它只是简单
的投出数据报。无连接的操作是快速和高效的。
2.  TCP和UDP协议的比较与介绍
Socket有两种主要的操作方式:面向连接的TCP协议和无连接的UDP协议。
面向连接的Sockets操作必须建立一个连接才能进行通信。在这个连接中传递的所有数据
是有序的,而且遵循先进先出的原则。
无连接的Sockets操作就像是一个邮件投递,数据投递过程中的安全性没有什么保证,而
且多个数据包在到达时的顺序可能与出发时的顺序不一样。
对信息的安全性、可靠性要求比较高的话,用面向连接的操作会好一点,在网络中实现
文件传输服务,这时对数据的正确性和有序性要求非常严格,如果其中的一些数据发生
了丢失,系统都不能正确的运行。但是,有的服务只需要间歇性的重复发送一些数据包
,即使部分数据发生丢失,由于很快又要重发,或者当数据到达的时候它可能已经过时
了,这个时候就需要使用无连接的Socket通信模式。
TCP UDP
1.通信的双方建立连接(Connection)
2.建立连接的双方可以相互发送或接收信息
3.可以保证数据被安全的送至目的地
4.数据传递过程中是按照先进先出的原则顺序传递的
5.对系统资源要求较大
6.系统响应速度慢
7.用数据流模式传递数据
8.TCP Server需要用Listen监听端口,并用Accept方法产生阻塞
9.目标地址在Connection时一次指定后即可,以后通过数据流进行数据交互 1.不需要
建立连接(Connection)
2.信息发送是单方向的
3.数据是否送达无法得到保证
4.数据传递是无序的
5.对系统资源的要求较少
6.系统响应速度极快
7.用数据报的方式传递数据
8.不需要调用Listen和Accept
9.目标地址在每个数据报中
表:TCP与UDP比较
但是并不是使用TCP就明显比UDP有优势
以下为UDP协议的适用范围:
发送的数据长度较短
拥有大量的客户端时
对数据的安全性没有特别的要求
网络负担较重,但对响应速度的要求较高
二. TCP协议通信的响应流程
TCP协议的实现是需要消息发送方和消息接收方建立数据通信连接(Connection)的。首
先,充当服务器端的应用程序需要对一个端口进行监听,当另外一个充当客户器端的应
用程序发出请求后,立即给予回应,并建立连接(Connection)。
具体响应过程如下图,图中(1)(2)(3)(4)(5)(6)(7)七个步骤表示一个完
整的TCP请求和响应的全部过程。对整个过程的详细介绍如下:
(1)  首先,Server端应该在所有的Client请求前创建Socket Server。
(2)  该Socket Server监听本机的一个端口,此时,服务器端处在阻塞状态,等待用户
的请求。
(3)  这时,Client端可以创建一个Socket,用于在后面的步骤中和服务器端程序进行
数据通信。
(4)  向服务器端的程序发送请求。
(5)  服务器端的Listener得到该请求后,创建和该客户端的连接。然后继续监听本机
指定的端口,并发出阻塞,直至下一个请求出现。
(6)  Server端和Client端利用刚才创建的连接进行数据通信。
(7)  通信完毕后,Server端和Client分别关闭各自的连接。
图 TCP协议响应示意图
三. 几个重要对象的介绍
1.  TcpListener和TcpClient
TcpListener对象是用来实现在服务器端监听,来自TCP的客户端程序连接的请求。该对象
从Socket对象继承而来,提供了TCP服务更高级的支持。很多的应用级协议是基于该对象
实现的,例如HTTP和FTP。
1) TcpListener对象所提供的最常用的方法
构造方法(Constructor Method)
最常用的两个:public TcpListener (int);
public TcpListener (IPAddress,int);
这两个方法分别用于从指定监听本机IP地址上指定的端口号,或指定IP地址上指定的端
口号。
注意:调用该构造方法的时候,系统并没有立即发生阻塞,进行监听。该方法只是指定
要监听的端口号。只有调用AcceptSocket或AcceptTcpClient方法时,系统才真正发生阻
塞,并开始等待客户端的响应。
还有一点:当使用构造方法TcpListener(IPAddress,int)时,
其中第一个参数IPAddres
s是一个对象,要将字符型的IP地址转变为IPAddress对象如下可以实现:
TcpListener SvrLsn = new TcpListener(IPAddress.Parse("192.168.0.14"),13);
Start方法
该方法用于启动一个TCP服务器的监听服务
Stop方法
该方法用于停止一个TCP监听服务
AcceptSocket或AcceptTcpClient方法
这两个方法都可以使系统发生阻塞,并监听指定端口。直至有TCP客户端的连接请求,该
方法才会返回一个客户端请求的案例,并继续执行后面的程序。
AcceptSocket和AcceptTcpClient方法的区别在于:返回的案例对象不同。
AcceptSocket方法是将一个客户端的TCP请求作为一个Socket案例返回。
AcceptTcpClient方法是将一个客户端的TCP请求直接返回。
返回Client Socket案例可以实现更加复杂的操作;但如果只是需要简单的和TCPClient
进行通信,那么使用AcceptTcpClient方法会更加简单。
下面是一个最简单的服务器端程序的原型。包括:启动、监听、发送数据、终止四个步
骤。
//启动一个TcpListener,并指定用于通信的端口号为13;
TcpListener myListener = new TcpListener(13);
myListener.Start();
//程序开始阻塞,直到有客户端的请求为止。mySocket是发出请求的客户端案例,在后
面可以通过对mySocket案例操作,实现对客户端请求的操作
Socket mySocket = myListener.AcceptSocket();
String str = "hello world";
//将字符串转化成为字符数组,(因为,Send方法发送只能发送字符数组)并发送给my
Socket;
Byte [ ] byteLine = System.Text.Encoding.ASCII.GetBytes(str.ToCharArray());
socket编程聊天室基本流程mySocket.Send(byteLine,byteLine.Length,0);
//终止TcpListener对端口的监听;
myListener.Stop();
2) TcpClient对象所提供的最常用的方法
GetStream方法
该方法返回一个NetworkStream对象的案例。通过这个NetworkStream的案例,可以和远
端客户端进行数据通信(包括数据发送和接收等操作)
Connection(IPAccess,int)方法
该方法需要由客户端程序所调用,用于和指定IP地址和端口号的远端主机建立连接。
当该方法被调用后,服务器端程序由AcceptTcpClient方法而引起的阻塞将被解除,服务
器端的程序可以得到本客户端程序TcpClient的案例进行通信。
Close方法
关闭TCP连接
下面的这段程序是一个最简单的客户端程序的原型,包括:启动、连接、发送数据、终
止四个步骤。
//启动一个TcpClient,并向IP地址为192.168.0.14的服务器13号端口发出连接请求;
TcpClient Clt = new TcpClient();
Clt.Connect(IPAddress.Parse("192.168.0.14"),13);
//将和服务器的连接重新定位到数据流(NetworkStream),并通过该数据流向服务器端
程序发送数据;
Strm = Clt.GetStream ();
System.Byte [ ] Sends = System.Text.UnicodeEncoding.Unicode.GetBytes(Sen
der.
ToCharArray());
Strm.Write(Sends,0,Sends.Length);
Strm.Flush();
//终止与服务器的连接;
Clt.Close ();
2.  Network Stream
从字面上可以看出,Network Stream是网络数据流处理的对象。该对象提供通过数据流
的方式,在网络中发送或接收数据,它提供同步和异步两种方法访问网络数据流。
其提供的最常用的方法如下:
CanRead方法
该方法可以得到当前数据流是否支持数据的"读"操作。实际上,此方法经常被用于检测
网络连接是否可用。
CanWrite方法
该方法可以得到当前数据流是否支持数据的"写"操作。
int Read (out byte[] buffer,int offset,int size)方法
该方法用于从网络数据流中读出数据,并放置在byte数组buffer中。
该方法的三个参数分别表示:用于存放数据的数组,读出的数据从数组的offset位置开
始存放,读出的字节数。
注意,要将byte数组的buffer的宽度定义的足够大,以免读出的数据过大而丢失。
Write(byte[ ] buffer,int offset,int size)
该方法用于向网络数据流中发送数据。
该方法的三个参数表示:将要发送的数据存放在数组buffer中,从数组的offset位置开
始读取size字节数,然后发送到网络数据流中。
3.  Thread
在服务器端的程序中,需要新建一个线程,用于等待由AcceptSocket活着AcceptTcpCli
ent方法引起的阻塞。这时,主线程并没有发生阻塞,仍然可以响应各种系统事件和操作
线程的另一个典型应用是当客户端程序与服务器建立连接后,通常需要为每个客户端的
连接在服务器端建立对应的线程。即,所有的客户端请求都在服务器端有一个独立的线
程来处理。当与客户端的连接中断后,其对应的线程也被终止。
常用的线程操作方法:
构造方法(Constructor Method)
最常用的构造方法,它有一个ThreadStart对象的参数。通常的调用方法如下:
Thread Th = new Thread(new ThreadStart(this.StartListen));
Th.Start();
该行程序实现了把this.StartListen方法在一个新的线程中启动。
Start方法
该方法用于启动一个新的线程
Abort方法
该方法用于终止一个已经存在的线程 

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。