多线程与Socketliyuestu.pptx

上传人:tia****nde 文档编号:20879901 上传时间:2021-04-20 格式:PPTX 页数:58 大小:2.48MB
收藏 版权申诉 举报 下载
多线程与Socketliyuestu.pptx_第1页
第1页 / 共58页
多线程与Socketliyuestu.pptx_第2页
第2页 / 共58页
多线程与Socketliyuestu.pptx_第3页
第3页 / 共58页
资源描述:

《多线程与Socketliyuestu.pptx》由会员分享,可在线阅读,更多相关《多线程与Socketliyuestu.pptx(58页珍藏版)》请在装配图网上搜索。

1、1 class Super public int field = 0 ; public int getField() return field; class Sub extends Super public int field = 1 ; public int getField() return field; public int getSuperField() return super.field; public class FieldAccess public static void main(String args) Super sup = new Sub(); / Upcast Sys

2、tem.out.println(sup.field = + sup.field + , sup.getField() = + sup.getField(); Sub sub = new Sub(); System.out.println(sub.field = + sub.field + , sub.getField() = + sub.getField() + , sub.getSuperField() = + sub.getSuperField(); sup.field = 0 , sup.getField() = 1sub.field = 1 , sub.getField() = 1 ,

3、 sub.getSuperField() = 0 2 class FatherClass protected class Gift public Gift() System.out.println(FatherClass.Gift(); public void f() System.out.println(FatherClass.Gift.f(); private Gift y = new Gift(); public FatherClass() System.out.println(New FatherClass(); public void insertGift(Gift yy) y =

4、yy; public void g() y.f();public class SonClass extends FatherClass public class Gift extends FatherClass.Gift public Gift() System.out.println(SonClass.Gift(); public void f() System.out.println(SonClass.Gift.f(); public SonClass() insertGift(new Gift(); public static void main(String args) FatherC

5、lass e2 = new SonClass(); e2.g(); FatherClass.Gift()New FatherClass()FatherClass.Gift()SonClass.Gift()SonClass.Gift.f() 1彼此独立,“同时”工作 什 么 是线程?l线程是一个程序(进程)内部的顺序控制流,必须依赖于进程中执行,一个进程可实现多个线程,同时完成不同的任务。l多线程意味着一个程序的多行语句同时执行,并不是多次启动同一个程序。l不同进程的代码、内部数据和状态都是独立的,而进程中的多线程是共享同一内存空间和同一系统资源,可能会相互影响。 线程两种实现方 法 :继承Th

6、read类和继承Runnable接口 用继承方式创建线程 很简单,只需要继承java.lang.Thread类,并覆盖Thread类的run方法。Thread类有两个很重要的方法:run方法和start方法lRun方法是加入需要执行代码的地方,是线程体,但不能直接调用,需要通过调用start方法启动线程(初始化相关资源)并运行run方法。但是因为java不支持多继承,如果已经继承了其他类就无法在继承Thread类了。这样就要通过实现接口来创建线程了。 用实现接口方式创建线程通过实现java.lang.Runnable接口来创建多线程,该接口只有一个run方法,重写就好了。但是,必须要调用Thr

7、ead类构造方法public Thread(Runnable target)来创建Thread类的实例才能提供对多线程的支持。下 面 是例子: public class ThreadSynTest implements Runnableprivate int num = 10;public void doit()if(num0)try Thread.sleep(1000); catch (InterruptedException e) / TODO Auto-generated catch blocke.printStackTrace();System.out.println(tickets+

8、-num); Overridepublic void run() /重写run方法/ TODO Auto-generated method stubwhile(true)doit();public static void main(String args) ThreadSynTest t = new ThreadSynTest();Thread a=new Thread(t);/新建线程Thread b=new Thread(t);Thread c=new Thread(t);Thread d=new Thread(t);a.start();/执行线程b.start(); c.start();

9、d.start();tickets9tickets8tickets9tickets7tickets5tickets6tickets4tickets3tickets2tickets1tickets0tickets-1tickets-2 线程很简单,就是一个在后台偷偷运行的“小(副)程序”,它的run()方法相当于主程序的main()方法,只不过要调用start()来启动它,也可以用一些指令将它暂停或者继续运行。其实我们天天都在接触线程,只不过我们的程序都是单线程(main方法)。新建一个线程并start()它,就相当于打开了一个新程序。多个线程一般平等地交叉运行,因为时间很短,故可以认为是同时运

10、行。 想象一下,现在我们的程序是模拟银行的运行。如果只有一个工作人员负责接待成百上千名客户,并为他们办理业务,可不可行?当然不行,除非你的银行无论在什么时候都最多只有一位客户光临。现在有这样一个策略:假设员工休息室里有很多业务员在休息,当他们接到前台接待的通知,就找一个业务员出去为客户办理业务,办理完了就回来休息。显然前台只要一个就够了,而柜台业务员则需要很多。 线程简单来讲,是这样的单线程 多进程 多线程一个人对一个帖子 十个人对十个帖子一个人对十个帖子 创建线程,可以 1 .继承Thread类,重写run()方法,使用start()方法启动线程。class huaji extends Th

11、read . public void run()水贴;.public static void main(String args) huaji xiaohuaji; xiaohuaji.start();继承Thread类,以创建多线程run()方法中说明这个线程要执行什么(但不能直接调用,需要通过调用start方法启动线程(初始化相关资源)并运行run方法。)创建一个线程并执行run()里面的内容 2 .实现Runnable接口中的run()方法,并通过Thread的构造方法public Thread(Runnable target)创建Thread实例class huaji implement

12、s Runnbale . public void run()水贴;.public static void main(String args) new Thread (new huaji).start(); 创建一个Thread对象并执行其start()方法 2接待客户,呼唤柜台业务员 socket(摘自百科网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket,通常也称作套接字,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。课本中的Socket例子包含一个服务端和客户端。服务端通过监听某个端口,等待客户端的连接;客户

13、端通过已知服务端的ip地址以及开放端口,连接到指定服务端。它们之间通过流的形式进行信息的交流。即把创建对方为自己的一个Socket实例,并通过 输入和输出两个流通信。也就是说,现阶段我们要写好Socket,就要掌握Socket的连接以及流的使用。后续代码参考课本PS:其实服务端和客户端的区别在于服务端相对固定,客户端通过服务端的信息来找到他,开始交流。相当于楼主发了个帖子,大家进去批判他,而不是楼主去找大家谈人生。在交流方式上,是相同的。 一、简 单理解Socket(1)Socket是什么? socket=套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象

14、为几个简单的接口供应用层调用已实现进程在网络中通信。 -来自网络 个人理解 就是一条数据线的作用 (不用想那么复杂) 个 人理解服务器 客户端创建并提供端口链接上IP地址,再接端口BufferedRead流(读入数据)PrintWriter流(发送数据) 简 单来说:可以把socket想象为以下过程:服务器=房子 端口=房子里的插座 客户端=手机现在要把手机连上插座充电,那么你首先得走进房子(连接上服务器IP地址),再找到插座(端口),同时连接手机(客户端)和插座(端口)需要数据线(socket)作为中介,这样两边才能进行正常的数据交换。 PS:同时前面解释了一个问题:怎样判别连接上的端口就是

15、想要连接的服务器的?类比一下类的封装特性,可以把端口看做封装在服务器中的成员,要想连接上服务器端口,首先得获取入口(服务器地址),然后才能通过IP查询到服务器的端口位置,避免出现多个服务器之间共用端口的情况(不同服务器IP地址是独一无二的). (3 )代码部分解释服务器端+客户端: ServerSocket s =new ServerSocket(PORT)利用ServerSocket类创建端口s对象,用于接收客户端数据以及提供端口 Socket socket=s.accept()利用Socket类创建socket对象接收数据 InetAddress addr = InetAddress.ge

16、tByName(null):如果向getByName()传递一个null(空)值,就默认为使用localhost。我们用InetAddress对特定的机器进行索引,而且必须在进行进一步的操作之前得到这个InetAddress(互联网地址)。 socket.close()+s.close(): finally中关闭对象 PrintWriter out = new PrintWriter(new 创建打印输出对象 BufferedWriter(new 缓冲区数据流输出 OutputStreamWriter(socket.getOutputStream(),true); 数据输出流 socket对象

17、获取向外输出数据 out.println():直接输出并发送括号中的数据 BufferedReader in = new BufferedReader(new 创建缓冲区数据流读取对象 InputStreamReader(socket.getInputStream() 输入数据流读取 socket获取输入数据 String str=in.readln():整行读入发送来的数据 以上是socket简单框架的代码,写的时候再: import java.io.*; import .*;加上: trycatchfinally即可至多:extends Thread,用run实现多线程个人代码都是在此基础

18、上加上框架和程序功能实现代码而已,待扩展的地方很多。 什 么 是 Socket?端口:一般而言,一台计算机只有单一的连接到网络的物理连接(Phy Connection),所有的数据都通过此连接对内对外送达特定的计算机,这就是端口。 但网络程序设计中的端口并非真实的物理存在,而是被规定为0 -6 5 5 3 5之间的整数。网络程序设计中的套接字(Socket)用于将程序和端口连接起来。 套接字分为(服务器程序)ServerSocket和(客户机程序)Socket其实,Socket肯定用于创建某种Reader以及/或Writer(或者InputStream和/或OutputStream)对象,这是

19、运用Socket的唯一方式。 ServerSocket服务器套接字ServerSocket主要功能是等待来自网络上的“请求”,一般使用构造方法ServerSocket(int port)来绑定到指定接口等待连接。ServerSocket server =new ServerSocket(8080);调用accept()方法会返回一个和客户端Socket对象相连接的Socket对象。 Socket socket=server.accept(); 客户端Socket构造方法一般为Socket(String host,int port),前一个参数是要连接的IP地址,后一个是要连接的端口。clien

20、t = new Socket(InetAddress.getByName(null),8080); 多线程Socket例子服务器端:import .*;import java.io.*;class Mult extends Thread/用继承方式实现多线程private Socket socket;/输入流和输出流private BufferedReader in;private PrintWriter out;public Mult(Socket s) throws IOExceptionsocket = s;/由Socket得到输入流和输出流实例对象in = new BufferedRe

21、ader(new InputStreamReader(socket.getInputS tream();out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),true);start();/开启线程 public void run()/重写run方法,线程体trywhile(true)/无限循环,读入数据String str = in.readLine();if(str.equals(END)/跳出循环条件break;System.out.println(Echoing:

22、+ str);out.println(str);/数据输出System.out.println(closing.);catch(IOException e) finallytry/如有异常,关闭socketsocket.close();catch(IOException e)续: public class ServerSocketMultstatic final int PORT = 8080;/端口号public static void main(String args) ServerSocket s=new ServerSocket(PORT);/创建服务器套接字System.out.pr

23、intln(Server Started);trywhile(true)/* * 无限循环接收客户套接字连接请求 */Socket socket = s.accept(); try/每接受一次请求创建一个新的Mult对象实例,运行一个新的线程new Mult(socket);catch(IOException e)socket.close();finally/最后关闭服务器套接字s.close(); 续: Socket的连接(参考课本简单来说服务端程序(楼主):public static final int PORT =8 0 8 0 ; /选定了一个端口.ServerSocket s=new

24、 ServerSocket(PORT); /通过该端口创建了服务端实例(帖子)服务端程序(楼主):Socket socket=s.accept(); /此时,通过accept()方法等待回帖的人,并创建一个客户端的实例。客户端:Socket socket =new Socket(addr,PORT);通过addr和PORT把服务端创建为一个Socket实例,其中addr为服务端ip地址,PORT为服务端开放端口。 已经建立联系,可以互喷了(x Socket的流(参考课本简单来说现在服务端和客户端都分别把对方创建为了一个Socket对象,然后声明了两个流in=new BufferedReader

25、(new InputStreamReader(socket.getInputStream();out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),true);这里 in 是对方的输出流,out是对方的读入流 服务端客户端out.println(内容); out.println(内容);in.readLine();in.readLine(); SocketSocket能实现的只有流的传输,本质上只是信息的交换,那么这些信息能干什么,就决定了这个程序的用途。至于多线程服务端里大

26、家有没有觉得课本里run()里面的东西很熟悉,没错简单来讲只是把流的操作写了进去。正如前面所说,run()方法里面是线程所要实现的功能,那么在这里对于架设好的服务端,需要每个线程重复操作的只是对每个接入客户端的流的处理。与之对应的客户端在多线程里就是把每个线程客户端所要对流的处理放进run()里面即可。 Socket简单来说,课本里多线程socket是这么一个情况。其实,一般服务端写成多线程就ok了吧吧。服务端 客户端 前台,也就是接待员的工作很简单,很机械。看见客户来了,就说“欢迎光临,请您到*柜台办理业务。”然后打电话到员工休息室,叫一名业务员出来负责处理该客户的业务。他大多数的时间都用在

27、等待新客户的光临上面,相当于ServerSocket的accept()方法。 如果你要到银行办理业务,你是不是得要先知道银行在哪?比如*区*街道。这个银行的地址相当于ServerSocket的IP地址。但是知道哪个街道还不行,因为整条街这么多店铺,有时还不止一家银行,所以我还要知道几号几零几才行。这个就相当于端口号。(IP负责找到运行服务器程序的电脑,端口号负责找到这台电脑哪个程序才是服务器程序) 知道了地址,我们只需要call一辆出租车让他送我到指定地点就行了,我们完全不用管具体要怎么走。这相当于客户端程序中Socket s = new Socket(IP,Port);到达银行后,等待已久的

28、前台接待马上会招呼你,并让你到指定柜台办理业务了。 办理业务的方式就很简单啦,你说我做,你问我答。客户不需要清楚业务员是怎样操作电脑把钱存进去的。业务员不能自作主张,客户说啥你就做啥,如果需要更多信息,问一下客户就是。这里的说相当于流的Write()方法,听相当于Read()方法。 一个人的耳朵和嘴巴肯定是独立的啦,同时执行完全不同的任务。不可能因为耳朵要准备接受信息,而导致嘴巴没法说话,大脑无法思考。(试想一下单线程时的Read()方法,你就懂我在说啥)所以客户端需要一个专门听(和准备听)对方说话的线程(我称它为耳朵线程)。一般柜台业务员就只有耳朵线程,因为他不能有创造,无需有思考,只用听用

29、户的话,完成相应指令就好。(符合网络通讯的“请求-响应”模型。 建立与连接服 务 器 任 务 : 等 候 建 立 一 个连接 ServerSocket s,然 后 就 此连接 创 建 Socket对 象 , 并 调 用 accept(),直到某个 客 户尝试 请 求连接然 后 创 建 一 个 IS和 OS,读入与反馈信 息 客 户 程 序获得本地 主 机 IP地 址 addr后 建 立 一 个 Socket对 象 ,并 请 求 与 服 务 器连接 正确建 立 与连接结果 :客 户未创 建且未请 求连接 :正确: accept()接收到连接 请 求 , 成功输出 connection accep

30、ted未连接 : accept()一直在 等 待连接失败: Socket不再存 在 , 调 用 s.closet(); 服务器与客户的沟通交流服 务 器 的 in读取客 户 的 out,服 务 器 的 out反馈给客 户 in;客 户 的 in读取服 务 器 的 out,客 户 的 out发送给服 务 器 in 客 户 不读不发送 :服 务 器读取反馈失败,关闭连接*若服 务 器 没 有 设置终止跳出 , 则 会 一直等 待读取 客 户 只读不发送 : 服 务 器 一直在 等 待 信 息 , 客 户 能读取服 务 器发送 的 信 息 客 户 只发送 不读取:客 户发送 信 息 后 无 其余动

31、作 则退出服 务 器若有终止跳出 则抛出异常,否则 一直等 待读取 服 务 器 不读不反馈: 服 务 器 一直监测客 户 服 务 器 只读不反馈: 服 务 器 一直读取, 客 户 端 也 一直等 待反馈 服 务 器 只反馈不读: 服 务 器 一直监测客 户 , 客 户 能 接收服 务 器 信 息 /Server_Socket.java public static void main(String args) throws IOException ServerSocket s = new ServerSocket(PORT); /创建ServerSocket。如果创建失败会自动退出程序 Syst

32、em.out.println(Started: + s); try /用try-finally块保证无论以什么方式结束,ServerSocket都会正确关闭 Socket socket = s.accept(); /调用accept()方法,暂时陷入停顿状态,直到有某个客户尝试同它建立连接,建立连接后会返回一个Socket对象 try System.out.println(Connection accepted: + socket);BufferedReader in = new BufferedReader(new InputStreamReader( socket.getInputStre

33、am(); /创建输入流,读取socket输入的文本内容 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), true);/创建输出流,准备向socket输出文本内容,每次println结束后自动刷新输出缓冲区服务端客户端accept()创建链接关闭抛出异常断开链接 while (true) String str = in.readLine(); /读取socket输入文本的一整行,直到遇到ENDif (str.equals(END) brea

34、k; System.out.println(Echoing: + str); /在服务器端输出收到的字符串 out.println(str + str + haha); /向socket客户端输出字符串 finally System.out.println(closing.); socket.close();/关闭与客户端的链接,readLine抛出异常。 finally s.close(); /关闭服务器端 服务端客户端输入流输出流输入流输出流 /Client_Socket.java public class Client_Socket public static void main(Str

35、ing args) throws IOException InetAddress addr = InetAddress.getByName(null); /获取主机名和IP号 System.out.println(addr = + addr); /创建Socket,用IP地址和端口号作为参数 Socket socket = new Socket(addr, Server_Socket.PORT); try /用try-finally块保证无论以什么方式结束,socket都会正确关闭 System.out.println(socket = + socket); BufferedReader in

36、 = new BufferedReader(new InputStreamReader(socket .getInputStream();/ /创建读取流,准备读取客户端Server_socket输入的文本内容 PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), true);/创建输出流,准备向客户端输出文本内容 /循环向服务器端输出,并读取服务端发来的数据for (int i = 0 ; i 1 0 ; i+) out.println(www

37、 + i);String str = in.readLine();System.out.println(str);out.println(END); finally System.out.println(closing.);socket.close(); /关闭客户端socket, readLine抛出异常 多线程服务端客户端accept()创建线程客户端客户端客户端 客户端创建线程创建线程创建线程创建线程客户端创建链接关闭抛出异常断开链接 /Mult.java继承Thread,作为单个线程执行的内容,内容和单线程的服务器端相似/构造器中用参数绑定链接的客户端socket = s;/start

38、()开始执行run()方法里面的内容,run()方法里的内容和单线程的服务器端相似start(); /ServerSoketMult.javapublic static void main(String args) throws IOException ServerSocket s = new ServerSocket(PORT);System.out.println(Server Started);try while (true) /每次有客户端连接的时候,都会生成一个socket对象,开一个线程进行与单线程客户端相同的工作Socket socket = s.accept();try new

39、 Mult(socket); catch (IOException e) socket.close(); finally s.close(); JAVA网络模型 服务单 个 的客户端的 。就直接服务器端ServerSocket 创建port ServerSocket serverSocket = new ServerSocket(8 0 8 0 );然后Socket socket = serverSocket.accept();等待Client的 Socket连接。然后Client连接Server端指定的 port;Socket socket = new Socket(“localhost”, 8 0 8 0 ); 虽然有点扯,但编程就是这样

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

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!