C#程序设计 c# programming 网络编程 C#程序设计课程组
教学内容 TCP/IP概述 .Net网络编程基础 一个简单聊天应用
TCP/IP概述
TCP/IP协议与OSI参考模型 计算机网络协议 计算机网络协议是指连接在网络上的计算机进行相互通信的规则约定。
何为协议? to:广东省深圳市东城大道8-10号 中国网络广东公司网维中心 鹏飞 (收) 以寄信为例 , 正确的地址,姓名,邮政编号以及正确的格式才可以让信寄到收信人手中。 所谓网络协议(Protocol),就是使在网络中的通信双方能顺利进行信息交换而双方预先共同约定好并遵循的规程和规则。 523129 鹏飞 (收) From: 国务院 刘先生 100000 to:广东省深圳市东城大道8-10号 中国网络广东公司网维中心
TCP/IP协议和OSI参考模型 7 6 5 4 3 2 1 TCP/IP协议栈具有简单的分层设计,与OSI参考模型有清晰的对应关系 应用层 表示层 会话层 传输层 网络层 数据链路层 物理层 应 用 层 7 6 5 4 3 2 1 OSI参考模型 TCP/IP
TCP/IP协议栈 数据链路层 物理层 TCP/UDP IP 接口和线缆 提供应用程序网络接口 应用层 传输层 建立端到端连接 HTTP、Telnet、FTP、 TFTP、Ping、etc TCP/UDP ARP/RARP IP ICMP 802.3 接口和线缆 应用层 传输层 网络层 数据链路层 提供应用程序网络接口 建立端到端连接 寻址和路由选择 物理介质访问 二进制数据流传输 物理层
TCP TCP是一种可靠的、面向连接的协议,并可以实现流控和差错控制。为必须使用可靠数据传输的程序提供支持,如数据库服务和电子邮件服务.
UDP UDP提供的是非连接的数据报服务,意味着UDP无法保证任何数据报的传递和验证。通常由每次传输少量数据或有实时需要的程序使用(QQ)
TCP与UDP比较
IP地址简介 为了使连入Internet的众多主机在通信时能够相互识别,Internet上的每一台主机和路由器都分配有一个唯一的32位地址。一个IP地址有4个字节组成,字节之间用句号分隔,每个字节表示为从 0 ~ 255 的十进制数(8位二进制数最大为 11111111 ,即十进制数255 11
子网(Subnet)
子网(Subnet) 65536个地址全部给一个网络 浪费资源 可以划分为256个子网,大大利用 了资源
端口号 TCP UDP IP 数 据 包 80 20/21 23 25 53 69 161 HTTP FTP Telnet SMTP DNS 传输层协议用端口号来标识和区分各种上层应用程序。 HTTP FTP Telnet SMTP DNS TFTP SNMP TCP UDP IP 数 据 包 80 20/21 23 25 53 69 161
.NET网络编程基础
命 名 空 间 命 名 空 间 功 能 概 述 System.Net 为当前网络上流行的多种协议提供一个统一、简单的编程接口。其中WebRequest和WebResponse类形成了“可插入协议”的基础,利用这种网络服务的实现,可以开发在使用Internet资源时不必考虑所用协议具体细节的应用程序 System.Net.Mail 用于将电子邮件发送到简单邮件传输协议(SMTP)服务器进行传送的类 System.Net.Mime 包含用于表示多用途Internet邮件交换(MIME)标头的类型。这些类型与System.Net.Mail命名空间中的类型一起使用,用于在使用SmtpClient类发送电子邮件时指定Content-Type、Content-Disposition和Content-transfer-Encoding标头 System.Net.Security 为网络流在主机间的传输提供了安全控制 System.Net.Sockets 为需要严格控制网络访问的开发人员提供Windows套接字(Winsock)接口的托管实现 System.Web 包含启用浏览器/服务器通信的类和接口。这些命名空间类用于管理到客户端的HTTP输出(HttpResponse)和读取HTTP请求(HttpRequest)。附加的类则提供了一些功能,用于服务器端的实用程序以及进程、cookie管理、文件传输、异常信息和输出缓存控制 System.Web.Mobile 包含生成ASP.NET移动Web应用程序所需的核心功能,包括身份验证和错误处理
主要的类 类 名 功 能 概 述 LingerOption 包含套接字延迟时间的信息,即当数据仍在发送时,套接字应在关闭后保持的时间 类 名 功 能 概 述 LingerOption 包含套接字延迟时间的信息,即当数据仍在发送时,套接字应在关闭后保持的时间 MulticastOption 包含了IP多点传送数据包的选项值 NetworkStream 为网络访问提供了基础数据流 Socket 实现了Berkeley套接字接口 SocketException 当出现套接字错误时,将抛出由该类所代表的异常 TCPClient 为TCP网络服务提供了客户连接 TCPListener 用以监听TCP客户连接 UDPClient 用于提供UDP网络服务
套接字编程 System.Net.Sockets名称空间包含允许直接发送TCP网络请求或侦听特定端口上的TCP网络请求的相关类 大量的方法和属性用于网络连接 提供客户端连接,用于创建和使用 TCP 网络服务 可用于为 UDP 客户端创建连接(它是 TCP 的备用协议,在本地网络上使用)
使用 TCP 类 TCP ( Transfers Control Protocol ,传输控制协议)类包含连接两个点并在这两个点之间发送数据的方法 一个点由 IP 地址和端口号组成。现有协议具有定义好的端口号 HTTP 使用端口号 80;SMPT 或电子邮件使用端口号 25; FTP 使用端口号 21 Internet Assigned Number Authority (IANA,Internet 编号分配管理机构)负责为这些有名的服务分配端口号 TCP 提供有保证的传送、错误更正和数据缓冲 TcpClient 类具有通过网络连接、发送和接收流数据的简单方法 TcpListener 类具有侦听进入的 TCP 连接的方法0
TcpClient 对象 属性 说明 ReceiveBufferSize 获取或设置接收缓冲区的大小 SendBufferSize 获取或设置发送缓冲区的大小 方法 说明 Close 关闭所有 TCP 连接并释放与 TcpClient 关联资源 Connect 将使用主机名和端口号将客户端连接至远程 TCP 主机 GetStream 返回用于发送和接收数据的NetworkStream
TCPListener 类的方法 方法 说明 AcceptSocket 返回与远程客户端通信的套接字 AcceptTcpClient TcpListener类具有侦听进入的TCP连接的方法,其中Start()方法用于开始侦听进入的连接请求,并且将把进入的连接放置在队列中,直到调用Stop()为止。AcceptSocket()或AcceptTcpClient()方法可用于从进入的连接请求队列中提取连接。 方法 说明 AcceptSocket 返回与远程客户端通信的套接字 AcceptTcpClient 接受暂挂的连接请求 Start 开始侦听进入的连接请求 Stop 关闭侦听器
UDP 类 方法 Receive() Send() Close() 当应用程序中速度和性能需求比可靠性更重要时,开发人员可以使用 UDP ( User Datagram Protocol ,用户数据报协议) 与 TcpClient 相比, UdpClient 类的接口更小且更简单。 UdpClient 不包含返回网络流以进行读写的方法 因为 UDP 是无连接协议,所以与远程主机的连接是在发送和接收数据时进行的 方法 Receive() Send() Close()
TCP应用编程
服务器对端口侦听 using System; using System.Net ; using System.Net.Sockets ; namespace Server { class Program{ public static void Main(string[] args) { //在本机创建一个TcpListener,端口是8888, TcpListener listener = new TcpListener(IPAddress.Any, 8888); //开始监听 Console.Write("Start listener . . . "); Console.ReadKey(true); }
客户机连接服务器 using System; using System.Net ; using System.Net.Sockets ; namespace Client{ class Program { public static void Main(string[] args) { Console.WriteLine("Client is runnning...!"); //生成一个TcpClinet TcpClient client = new TcpClient(); try{ client.Connect("127.0.0.1",8888); } catch (Exception ex) { Console.WriteLine (ex.Message ); return ; Console.Write("Server connect ..{0}-->{1}",client.Client.LocalEndPoint,client.Client.RemoteEndPoint);
服务器获取客户端连接 //在本机创建一个TcpListener,端口是8888, TcpListener listener = new TcpListener(IPAddress.Any, 8888); //开始监听, listener.Start(); Console.Write("Start listener . . . "); //接受客户端的连接,利用client保存连接的客户端 TcpClient remoteclient = listener.AcceptTcpClient(); Console.Write("Client connect ..{0}-->{1}",remoteclient.Client.LocalEndPoint,remoteclient.Client.RemoteEndPoint);
多客户端连接服务器 public static void Main(string[] args) { Console.WriteLine("Client is runnning...!"); TcpClient client; //生成一个TcpClinet for(int i=0;i<2;i++){ try{ client= new TcpClient(); client.Connect("127.0.0.1",8888); } catch (Exception ex) {Console.WriteLine (ex.Message ); return ; Console.WriteLine("Server connect ..{0}-->{1}",client.Client.LocalEndPoint,client.Client.RemoteEndPoint);
多客户端连接服务器 public static void Main(string[] args) { //在本机创建一个TcpListener,端口是8888, TcpListener listener = new TcpListener(IPAddress.Any, 8888); //开始监听, listener.Start(); Console.WriteLine("Start listener . . . "); while (true ) { //接受客户端的连接,利用client保存连接的客户端 TcpClient remoteclient = listener.AcceptTcpClient(); Console.WriteLine("Client connect ..{0}-->{1}",remoteclient.Client.LocalEndPoint,remoteclient.Client.RemoteEndPoint); }
同步字符串传输 public static void Main(string[] args) { Console.WriteLine("Client is runnning...!"); //生成一个TcpClinet TcpClient client; try{ client= new TcpClient(); client.Connect("127.0.0.1",8888); } catch (Exception ex) {Console.WriteLine (ex.Message ); return ; string Msg="Hello server ,I'm Client!"; Console.WriteLine (Msg ); NetworkStream streamToServer=client.GetStream (); byte[] buffer= Encoding.ASCII.GetBytes(Msg);//将字符串转化为字节 streamToServer.Write (buffer ,0,buffer.Length ); Console.ReadKey ();
public static void Main(string[] args) { const int BufferSize=8192; //在本机创建一个TcpListener,端口是8888, TcpListener listener = new TcpListener(IPAddress.Any, 8888); //开始监听, listener.Start(); Console.WriteLine("Start listener . . . "); //接受客户端的连接,利用client保存连接的客户端 TcpClient remoteclient = listener.AcceptTcpClient(); NetworkStream streamToClient = remoteclient.GetStream(); byte[] buffer=new byte[BufferSize]; int byteRead=streamToClient.Read (buffer ,0,BufferSize ); string Msg= Encoding.ASCII.GetString(buffer ,0,byteRead );//将字符串转化为字节 Console.WriteLine ("Reveive :{0}",Msg ); Console.ReadKey (); }
服务器回复,客户机收到并输出 public static void Main(string[] args) { const int BufferSize=8192; //在本机创建一个TcpListener,端口是8888, TcpListener listener = new TcpListener(IPAddress.Any, 8888); //开始监听, listener.Start(); Console.WriteLine("Start listener . . . "); //接受客户端的连接,利用client保存连接的客户端 TcpClient remoteclient = listener.AcceptTcpClient(); NetworkStream streamToClient = remoteclient.GetStream(); byte[] buffer=new byte[BufferSize]; int byteRead=streamToClient.Read (buffer ,0,BufferSize ); string Msg= Encoding.ASCII.GetString(buffer ,0,byteRead );//将字符串转化为字节 Console.WriteLine ("Reveive :{0}",Msg ); Msg=" Hello client,I am Server"; Console.WriteLine("Send to Client:{0}",Msg ); buffer =Encoding.ASCII.GetBytes(Msg);//将字符串转化为字节 streamToClient.Write (buffer ,0,buffer.Length ); Console.ReadKey (); }
public static void Main(string[] args) { int BufferSize=8192; Console.WriteLine("Client is runnning...!"); //生成一个TcpClinet TcpClient client; try{ client= new TcpClient(); client.Connect("127.0.0.1",8888); } catch (Exception ex) {Console.WriteLine (ex.Message ); return ; string Msg="Hello server ,I'm Client!"; Console.WriteLine ("Clent Send:{0}",Msg ); NetworkStream streamToServer=client.GetStream (); byte[] buffer= Encoding.ASCII.GetBytes(Msg);//将字符串转化为字节 streamToServer.Write (buffer ,0,buffer.Length ); int byteRead;//收到的字节数 buffer =new byte[BufferSize]; byteRead =streamToServer.Read (buffer ,0,BufferSize ); Msg= Encoding.ASCII.GetString(buffer ,0,byteRead );//将字节转化为字符串 Console.WriteLine ("Receive Server:{0}",Msg ); Console.ReadKey ();
总结 端口是特定机器上已编号的套接字。服务器进程侦听端口,直到有客户端与其连接为止 TcpClient 类有可用于连接、发送和接收流数据的方法;TcpListener 类具有侦听进入的 TCP 连接的方法