和网络编程-01-多线程socket_第1页
和网络编程-01-多线程socket_第2页
和网络编程-01-多线程socket_第3页
和网络编程-01-多线程socket_第4页
和网络编程-01-多线程socket_第5页
免费预览已结束,剩余46页可下载查看

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

北京传智播客教育聊天程序(Thread、Socket)讲师:赵晓虎委托委托语法(定义、声明、使用)多播委托委托作为参数、返回值lambda表达式使用Func(必须有返回值)、Action(没有返回值)List<T>的FindAll(Predicate<T>match)方法演示,查看内部实现文件流FileStream、StreamReader、StreamWriterstring→byte[]和byte[]→string如何转换?复习:多线程进程(Process):一个进程就是一个正在执行的程序的实例(各种资源的容器,它定义了一个地址空间,作为基本的执行环境)。它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另一个进程的数据,一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。多任务操作系统进程之间快速切换。“程序”与“进程”的区别(一个程序运行了两次,算是两个进程(两个进程恰好运行同一个程序))。举例:做蛋糕(原料input、食谱algorithm、我cpu)进程就是拿来原料,看食谱、做蛋糕等一系列动作的总和。此时某人被欺负受伤了,此时记录下食谱做到了第几步,取出急救手册去帮助治伤(优先级高),治好伤后回来继续做蛋糕,从上次记录的步骤后继续做。windows中进程没有层次概念,所有进程的地位都是相同的。每个进程都有一个地址空间和一个控制线程。操作系统会维护一个全局进程表线程(Thread):是Windows任务调度的最小单位。线程是进程中的一个执行流(执行序列),每个线程都有自己的专有寄存器(栈指针、程序计数器(下一条要执行的指令)等),但代码区是共享的,即不同的线程可以执行同样的函数。可以把线程理解为一个独立的数据结构,里面存储了方法调用的栈、下一条要执行的指令等。一个进程中的多个线程亦可以共享该进程中的数据。使用线程注意:1.每个进程都要执行,所以每个进程至少有一个线程。2.某些操作会被阻塞(比如:阻塞UI相应用户的操作)3.创建一个线程要比创建一个进程快得多,线程间切换也比进程间切换快。4.合理使用多线程能大大提高应用程序性能(举例:如果多个任务都是cpu密集型的则使用多线程并不能提高性能返回会下降。)5.在多cpu的系统中使用多线程是有益的,实现了真正的并发执行。查看“任务管理器”每个进程中的线程个数。6.在一个进程中的多个任务有时是不能通过再创建多个进程实现的,因为要共享数据(比如Excel中同时要实现计算等功能,Vs开发工具语法错误以后红色波浪线提示等)。【进程用于把资源集中到一起,而线程则是在cpu上被调度执行的实体】线程之间是“平等”的,不存在“子父关系”,每个线程都有一个自己的唯一编号。程序1程序2线程1线程2线程3线程1线程2线程3多线程进程与线程一个进程至少有一个线程同一个进程中的多个线程之间可以"并发"执行*应用程序域(AppDomain)1.操作系统在不同应用程序之间的隔离。2.以前都是用进程来隔离。在.net平台下,现在可以使用AppDomain3.在同一个进程中可以包含多个应用程序域,使用多个应用程序域来隔离不同的应用程序,好处:不会造成进程间调用或进程间切换等方面的额外开销。4.能够在不停止整个进程的情况下停止单个应用程序AppDomain:它提供安全而通用的处理单元,公共语言运行库可使用它来提供应用程序之间的隔离。您可以在具有同等隔离级别(存在于单独的进程中)的单个进程中运行几个应用程序域,而不会造成进程间调用或进程间切换等方面的额外开销。优势:在一个应用程序中出现的错误不会影响其他应用程序。能够在不停止整个进程的情况下停止单个应用程序。应用程序域形成了托管代码的隔离、卸载和安全边界。在任意给定时间,每一线程都在一个应用程序域中执行。演示演示Process1.获取当前系统的所有进程GetProcesses()2.启动动某个进程Start()3.杀死一个进程Kill()演示AppDomain1.获取当前应用程序域名称2.创建一个应用程序域,在该应用程序域中启动一个exe程序集。演示Thread1.创建一个简单的线程2.带参数的(*)3.如何获取返回值BackgroundWorker演示1:遇到的一个问题演示2:解决该问题.net使用线程的步骤:1.命名空间System.Threading;2.创建Thread类。3.设置要在指定线程中执行的方法4.启动线程。IsBackground属性,前台线程和后台线程线程之间是平等的,看一个案例:关了窗体,只要有线程在运行,那么整个进程是不会退出的。前台线程:只有所有的前台线程都关闭才能完成程序关闭。只要有任何一个前台线程还在运行,则进程不会自动关闭。后台线程:只要所有的前台线程结束,后台线程自动结束。一般自己创建的线程都设置为后台线程。线程操作演示1.获取当前线程,当前线程的Id。Thread.CurrentThread.ManagedThreadId2.创建一个执行无参数无返回值的方法的线程并启动,在该方法中输出线程Id3.启动线程执行一个带参数的方法,使用newParameterizedThreadStart()4.将带参数的方法封装成一个类,把参数变成类的成员。然后通过newThreadStart()照样实现执行带参数的方法。(*)5.启动线程执行方法,并获取方法的返回值。两种思路:1>使用BackgroundWorker实现(备注1)。2>通过异步委托实现。8.跨线程调用windows窗体控件。6.实现大文件拷贝的进度条问题。7.摇奖机。Thread类的一些常用成员(*)构造函数:Thread(ParameterizedThreadStart),调用带一个参数的方法,参数类型objectThread(ThreadStart)调用无参数无返回值方法常用实例成员:Start()启动线程,导致操作系统将当前实例的状态更改为ThreadState.RunningAbort()终止线程,请求操作系统请终止该线程。Join()在继续执行之前,阻塞调用线程,直到某个线程终止为止。带参数的重载表示超时时间,如果超过超时时间,则线程不再阻塞继续执行。IsAlive如果此线程已启动并且尚未正常终止或中止,则为true;否则为false。IsBackground指示某个线程是否为后台线程。ManagedThreadId获取当前托管线程的唯一标识符。Priority获取或设置一个值,该值指示线程的调度优先级。ThreadState获取一个值,该值包含当前线程的状态。Name获取或设置线程的名称。静态成员:Thread.Sleep(1000)将当前线程挂起指定的时间。,可以使当前线程停止一段时间运行。Thread.CurrentThread属性,获取当前线程。线程同步lock案例1:观察代码说出执行结果。备注1.案例2:观察代码说出执行结果。备注2.为什么?变量的++操作其实可以分成3步来解释。解决办法:只要保证同时只能有一个线程操作_count变量即可。备注3.备注4.等价于lock的写法。lock锁定的类型只能是引用类型,不能是值类型,因为lock最后会编译成Monitor.Enter()与Monitor.Exit()。如果传递的是值类型,则在Monitor.Enter(100)的时候发生装箱,产生了一个对象,而在Monitor.Exit(100)的时候100又发生了装箱,则锁定时的对象与解锁的对象不是同一个对象,所以无效!注意:lock(obj)中锁定的obj对象必须是同一个对象才能起到互斥作用,如果lock(this)的话,不同的实例调用该方法锁的是不同的对象无法起到互斥作用,所以可以在类中,建一个静态的只读的object对象,然后所有实例锁定时都是锁定该object对象。案例:模拟SqlServer连接池主要理解lock关键字理解生产者消费者问题步骤:创建数组MyConnection数组创建四个创建MyConnection实例的线程,并往数组中添加实例(生产者)创建十个获取MyConnection实例的线程在使用lock和不使用lock的情况下做一下对比线程同步(*)new在堆上申请内存空间后干了什么Objectobj=newObject();//开辟内存//调用构造函数//同步块索引(负数)Lock(语法糖)Monitor.Enter(Obj)Monitor.Exit(Obj)同一个类型的多个对象共享一个“类型对象”死锁介绍线程池在程序中,如果某个创建某种对象所需要的代价太高,同时这个对象又可以反复使用,那么我们往往就会准备一个容器,用来保存一批这样的对象。于是乎,我们想要用这种对象时,就不需要每次去创建一个,而直接从容器中取出一个现成的对象就可以了。由于节省了创建对象的开销,程序性能自然就上升了ThreadPoolclass提供了一个线程池,该线程池可用于发送工作项、处理异步I/O、代表其他线程等待以及处理计时器。线程池允许在后台运行多个工作,而不需要为每个任务频繁地创建和销毁单独的线程,从而减少了开销。注意:线程池中的线程都是后台线程不能手动设置每个线程的属性,比如设置为前台线程、优先级等等当执行一些比较短的任务是考虑使用线程池,长时间执行的任务不要使用线程池来创建(其他任务一直在等),而要使用Thread手动创建一个线程。委托的异步调用(讲完线程再讲也行)BeginInvoke异步调用,BeginInvoke(被调用的方法的参数,回调函数,回调函数的参数);EndInvoke获取异步调用的(方法)返回值IAsyncResult异步操作的状态AsyncResult异步操作的结果(可以获取当前执行的委托对象)usingSystem.Runtime.Remoting.Messaging;AsyncState获取回调函数的参数。注意:委托的异步调用只对单播委托并行计算(*)了解一下.net4.0中Parallel.For//并行循环Parallel.ForEach//并行循环Parallel.Invoke()//并行调用几个委托网络编程--SOCKET协议栈网络之间传输数据需要协议。网络七层:应用层、表示层、会话层、传输层、网络层、链路层、物理层网络五层:应用层、传输层、网络层、链路层、物理层。一般因特网现在都是用的是五层协议,把表示层与会话层的功能都交给了具体的应用程序来做了。1应用层(HTTP、FTP、SMTP)报文Message2传输层(TCP、UDP)报文段Segment,为运行在不同主机上的应用程序进程间提供数据传输服务。通过套接字(Socket)实现。TCP(传输控制协议)面向连接的、可靠(应用:ftp、smtp、http等都是基于tcp)UDP(用户数据报协议)无连接的、不可靠的(数据报)应用:视频会议、网络电话、DNS解析。(速度快,能容忍部分数据丢失)3网络层(IP)数据报datagram,把数据从一台主机移动到另一台主机,主机间通信。IP协议不可靠,有丢包。4链路层(以太网、WiFi、点对点)帧Frame,负责将数据报传递给下一个节点。不同的链路层有特定的链路层协议。一系列路由器、交换机。5物理层:负责把数据一个bit一个bit的从一个节点移动到下一个节点,该层中的协议仍然与链路层相关。例如,以太网具有许多物理层协议:双绞铜线的、同轴电缆的、光纤的。【每一层都只考虑自己不关心其他。】四层协议举例两个人在两个房子里打电话的图人通过【电话】可以通信程序通过【Socket】来通信。*套接字就是程序间的电话机。Socket相关概念socket的英文原义是“孔”或“插座”。作为进程通信机制,取后一种意思。通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。(其实就是两个程序通信用的。)socket非常类似于电话插座。以一个电话网为例。电话的通话双方相当于相互通信的2个程序,电话号码就是IP地址。任何用户在通话之前,首先要占有一部电话机,相当于申请一个socket;同时要知道对方的号码,相当于对方有一个固定的socket。然后向对方拨号呼叫,相当于发出连接请求。对方假如在场并空闲,拿起电话话筒,双方就可以正式通话,相当于连接成功。双方通话的过程,是一方向电话机发出信号和对方从电话机接收信号的过程,相当于向socket发送数据和从socket接收数据。通话结束后,一方挂起电话机相当于关闭socket,撤消连接。端口的分类端口范围:0-65535之间。端口的意义:用来区分不同的进程。端口分为以下三类:(1)公认端口(WellKnownPorts):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯,ftp21,smtp25,....。(2)注册端口(RegisteredPorts):从1024到49151。它们松散地绑定于一些服务(某些大公司的某些软件,sun公司某个系统的某个服务等)。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。(3)动态和/或私有端口(Dynamicand/orPrivatePorts):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。但也有例外:SUN的RPC端口从32768开 始。netstat-a-n【-a显示所有端口,-n以数字形式显示】Socket相关概念[端口]在Internet上有很多这样的主机,这些主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务(应用程序)。例如:http使用80端口。ftp使用21端口。smtp25端口。23端口主要用于Telnet(远程登录)53端口为DNS(DomainNameServer,域名服务器。有两种类型:流式Socket(STREAM):

是一种面向连接的Socket,针对于面向连接的TCP服务应用,安全,但是效率低;发送数据是以流的方式,发送方可以有自己的缓冲区大小,接收方也可以有自己的缓冲区大小,不必一致,只要发送的数据都接收到就可以了。一次发10个字节,发3次。接收方一次接6个字节,接5次。只要保证最后是完整的就可以。数据报式Socket(DATAGRAM):

是一种无连接的Socket,对应于无连接的UDP服务应用.不安全(丢失,顺序混乱,在接收端要分析重排及要求重发),但效率高.发送方每次发送一个数据报,接收方必须一次也接收一个完整的数据报。Socket编程模型服务器端:1.创建Socket对象。设置协议、传输方式等(连接Socket)2.绑定IP与端口(设置要监听的IP与端口)。Bind()3.开启监听。Listen()4.开始接受客户端连接。Accept();//阻塞线程,同时也需要循环不断接受用户连接。5.接受了客户端的连接,生成一个新的Socket对象(通信Socket)6.接受(Receive)和发送(Send)消息//需要循环不断接收用户的消息7.Shutdown()禁用发送与接收功能。8.Close()关闭释放资源客户端:1.创建Socket对象。设置协议、传输方式等(连接Socket)2.Connect()连接服务器(IP与端口)3.向服务器发送、接受消息4.Shutdown()禁用发送与接收功能。5.Close();关闭释放资源Socket通信基本流程图连接通过构造函数完成。

publicSocket(AddressFamilyaddressFamily,SocketTypesocketType,ProtocolTypeprotocolType)AddressFamily

成员指定

Socket

用来解析地址的寻址方案。例如,InterNetwork

指示当

Socket使用一个IP版本4地址连接。SocketType

定义要打开的

Socket

的类型Socket

类使用

ProtocolType

枚举向WindowsSocketsAPI

通知所请求的协议Socket的构造函数

如:mySocket=newSocket(AddressFamily.InterNetwork,

SocketType.Stream,ProtocolType.Tcp);Demo1:监听Socket一般应用模式(服务器端和客户端)1.服务端ingsocket开始监听端口(负责监听客户端连接信息)

2.客户端clientsocket连接服务端指定端口(负责接收和发送服务端消息)

3.服务端ingsocket监听到客户端连接,创建connectionsocket。(负责和客户端通信)1.2.3.负责监听‘连接请求’的套接字客户端套接字负责和客户端通信的套接字Socket一般应用模式(服务器端和客户端)服务器端的Socket(至少需要两个)一个负责接收客户端连接请求(但不负责与客户端通信)每成功接收到一个客户端的连接便在服务端产生一个对应的负责通信的Socket在接收到客户端连接时创建.为每个连接成功的客户端请求在服务端都创建一个对应的Socket(负责和客户端通信).客户端的Socket客户端Socket必须指定要连接的服务端地址和端口。通过创建一个Socket对象来初始化一个到服务器端的TCP连接。

Socket的通讯过程服务器端:申请一个socket绑定到一个IP地址和一个端口上开启侦听,等待接授连接客户端:申请一个socket连接服务器(指明IP地址和端口号)服务器端接到连接请求后,产生一个新的socket(端口大于1024)与客户端建立连接并进行通讯,原监听socket继续监听。注意:至少要定义一个要连接的远程主机的IP和端口号。IP端口是一个逻辑端口,它的存在是为了让服务器上寄宿多个网络应用同时进行通信。一个IP地址的端口可以有65536(即:2^16)个之多.端口号必须在1和65535之间,最好在1024以后。要连接的远程主机必须正在监听指定端口,也就是说你无法随意连接远程主机。如:IPAddressaddr=IPAddress.Parse("");IPEndPointendp=newIPEndPoint(addr,10001); 服务端先绑定:eSocket.Bind(endp) 客户端再连接:clientSocket.Connect(endp)注意:一个Socket一次只能连接一台主机。Socket关闭后无法再次使用。每个Socket对象只能一台远程主机连接.如果你想连接到多台远程主机,你必须创建多个Socket对象。------------------相关类--------------------------IPAddress类:包含了一个IP地址IPEndPoint类:包含了一对IP地址和端口号--------------------方法们------------------------------Socket():创建一个SocketBind():绑定一个本地的IP和端口号(IPEndPoint)Listen():让Socket侦听传入的连接尝试,并指定侦听队列容量Connect():初始化与另一个Socket的连接Accept():接收连接并返回一个新的socketSend():输出数据到SocketReceive():从Socket中读取数据Close():关闭Socket(销毁连接)Socket方法Demo2:发送文字信息基于TCP的Socket编程processTCPwithbuffers,variablessocket由软件工程师控制由操作系统控制processTCPwithbuffers,variablessocketinternetclientserverSocket()Connect()Socket()Bind()Listen()accept()Send()Receive()Close()Close()ReceiveSend()TCPconn.requestTCPACK..Socket练习Demo1:演示建立连接Demo2:使用线程来侦听讨论:聊天机器人问题补充:1.解决当服务器与客户端建立连接后,直接关闭客户端窗口后造成的服务器端“远程主机强迫关闭了一个现有的连接。”问题。解决:在客户端窗口的FormClosing事件中关闭当前skClient:

if(skClient!=null){skClient.Shutdown(SocketShutdown.Both);skClient.Close();skClient.Dispose();skClient=null;}2.解决当客户端已经关闭后,调用skClient.Receive(buffers);方法造成的“一个封锁操作被对WS

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论