第3章线程和网络编程_第1页
第3章线程和网络编程_第2页
第3章线程和网络编程_第3页
第3章线程和网络编程_第4页
第3章线程和网络编程_第5页
已阅读5页,还剩84页未读 继续免费阅读

下载本文档

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

文档简介

第三章

线程和网络编程南京邮电大学通信与信息工程学院王诚wangc@Java实用编程技术与项目实战在操作系统中都会涉及处理机管理,即会引入一个进程的概念,它是动态的、相互隔离的、独立运行的、是资源分配单位及调度的基本单位进程是由进程控制块、程序段、数据段三部分组成线程是共存于一个进程中的多个并发执行流Java是第一个在语言本身中显式地包含线程的主流编程语言,而不是对底层操作系统的调用线程概念Java实用编程技术与项目实战进程与线程是有区别的。进程(process)本质上是一个并发执行的程序。因此,基于进程(process-based)的多任务处理的特点是允许你的计算机同时运行两个或更多的程序。基于线程(thread-based)的多任务处理环境中,线程是最小的执行单位,线程也称轻量级进程,共享进程的内存、文件句柄、和状态,单线程具有自己的堆栈、自己的程序计数器和自己的局部变量线程概念Java实用编程技术与项目实战多线程主要是为了节约CPU时间。多线程程序比多进程程序需要更少的管理费用。进程是重量级的任务,需要分配它们自己独立的地址空间。进程间通信是昂贵和受限的。进程间的转换也是很需要花费的,即进程切换需要花费大量处理机时间。而线程是轻量级的任务,共享相同的地址空间并且共同分享同一个进程。线程间通信是便宜的,线程间的切换也是低成本的线程概念Java实用编程技术与项目实战Java运行系统在很多方面依赖于线程,所有的类库设计都考虑到多线程。实际上,Java使用线程来使整个环境异步。这有利于通过防止CPU循环的浪费来减少无效部分Java是多线程处理模型。其优点在于取消了主循环/轮询机制。一个线程可以暂停而不影响程序的其他部分,即多个线程通过系统调度进行并发执行。在Java程序中出现线程阻塞,仅有一个线程暂停,其他线程继续运行Java线程模型Java实用编程技术与项目实战每个线程都有产生、运行、消亡的状态转换过程Java线程模型Java实用编程技术与项目实战创建状态(newThread):执行下列语句时,线程就处于创建状态:ThreadmyThread=newMyThreadClass();当一个线程处于创建状态时,它仅仅是一个空的线程对象,系统不为它分配资源,尚未执行(start()尚未调用)可运行状态(Runnable):当一个线程处于可运行状态时,系统为这个线程分配了它需的系统资源,安排其运行并调用线程运行方法,这样就使得该线程处于可运行(Runnable)状态。如执行:ThreadmyThread=newMyThreadClass();myThread.start();Java线程模型Java实用编程技术与项目实战不可运行状态(NotRunnable):不可运行状态也称为阻塞状态(Blocked)。因为某种原因(输入/输出、等待消息或其它阻塞情况),系统不能执行线程的状态。这时即使处理器空闲,也不能执行该线程。进入不可运行状态的原因有如下几条:调用了sleep()方法;调用了suspend()方法;为等候一个条件变量,线程调用wait()方法;输入输出流中发生线程阻塞。Java线程模型Java实用编程技术与项目实战死亡状态(Dead):线程的终止一般可通过两种方法实现:自然撤消(线程执行完)或是被停止(调用stop()方法)。不推荐通过调用stop()来终止线程的执行,而是让线程执行完Java线程模型Java实用编程技术与项目实战Java的多线程系统建立于Thread类。Thread类封装了线程的执行。为创建一个新的线程,你的程序必须扩展Thread或实现Runnable接口Thread类方法如下表:Java线程模型Java实用编程技术与项目实战Java线程模型方法意义getName 获得线程名称getPriority 获得线程优先级jsAlive 判定线程是否仍在运行join 等待一个线程终止run 线程的入口点.sleep 在一段时间内挂起线程start 通过调用运行方法来启动线程Java实用编程技术与项目实战Java程序至少包含一个线程,即当Java程序启动时,一个线程立刻运行,该线程通常叫做程序的主线程(mainthread),因为它是程序开始时就执行的。主线程的重要性体现在两方面:它是产生其他子线程的线程;通常它必须最后完成执行,因为它执行各种关闭动作主线程Java实用编程技术与项目实战尽管主线程在程序启动时自动创建,但它可以由一个Thread对象控制。为此,你必须调用方法currentThread()获得它的一个引用,currentThread()是Thread类的公有的静态成员。它的通常形式如下:staticThreadcurrentThread()该方法返回一个调用它的线程的引用。一旦获得主线程的引用,就可以像控制其他线程那样控制主线程主线程Java实用编程技术与项目实战publicclassTest{ publicstaticvoidmain(Stringargs[]) { Threadct=Thread.currentThread(); System.out.println("Currentthread:"+ct); ct.setName("Test"); System.out.println("Afternamechange:"+ct); try { Thread.sleep(1000); } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted"); } }}主线程Java实用编程技术与项目实战程序的运行结果:Currentthread:Thread[main,5,main]Afternamechange:Thread[Test,5,main]主线程Java实用编程技术与项目实战大多数情况,通过实例化一个Thread对象来创建一个线程。Java定义了两种方式:实现Runnable接口和继承Thread类创建线程的最简单的方法就是创建一个实现Runnable接口的类。Runnable抽象了一个执行代码单元。你可以通过实现Runnable接口的方法创建每一个对象的线程。为实现Runnable接口,一个类仅需实现一个run()的简单方法创建线程Java实用编程技术与项目实战在run()中可以定义代码来构建新的线程。理解下面内容是至关重要的:run()方法能够像主线程那样调用其他方法,引用其他类,声明变量。仅有的不同是run()在程序中确立另一个并发的线程执行入口。当run()返回时,该线程结束创建线程Java实用编程技术与项目实战classChildimplementsRunnable{ Threadt; Child() { t=newThread(this,"ChildtThread"); System.out.println("Childthread:"+t); t.start(); }创建线程Java实用编程技术与项目实战

publicvoidrun() { try { for(inti=5;i>0;i--) { System.out.println("ChildThread:"+i); Thread.sleep(500); } } catch(InterruptedExceptione) { System.out.println("Childinterrupted."); } System.out.println("Exitingchildthread."); }}创建线程Java实用编程技术与项目实战publicclassTest{ publicstaticvoidmain(Stringargs[]) { newChild(); try { for(inti=5;i>0;i--) { System.out.println("MainThread:"+i); Thread.sleep(1000); } } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted."); } System.out.println("Mainthreadexiting."); }}创建线程Java实用编程技术与项目实战该程序的输出如下:Childthread:Thread[ChildtThread,5,main]MainThread:5ChildThread:5ChildThread:4MainThread:4ChildThread:3ChildThread:2MainThread:3ChildThread:1Exitingchildthread.MainThread:2MainThread:1Mainthreadexiting创建线程Java实用编程技术与项目实战创建线程的另一个途径是创建一个新类来扩展Thread类,然后创建该类的实例。当一个类继承Thread时,它必须重载run()方法,这个run()方法是新线程的入口。它也必须调用start()方法去启动新线程执行创建线程Java实用编程技术与项目实战classMythreadextendsThread{ Mythread() { super("DemoThread"); System.out.println("Childthread:"+this); start(); }创建线程Java实用编程技术与项目实战publicvoidrun() { try { for(inti=5;i>0;i--) { System.out.println("ChildThread:"+i); Thread.sleep(500); } } catch(InterruptedExceptione) { System.out.println("Childinterrupted."); } System.out.println("Exitingchildthread."); }}创建线程Java实用编程技术与项目实战publicclassTest{ publicstaticvoidmain(Stringargs[]) { newMythread(); try { for(inti=5;i>0;i--) { System.out.println("MainThread:"+i); Thread.sleep(1000); } } catch(InterruptedExceptione) { System.out.println("Mainthreadinterrupted."); } System.out.println("Mainthreadexiting."); }}创建线程Java实用编程技术与项目实战当两个或两个以上的线程需要共享资源,它们需要某种方法来确定资源在某一刻仅被一个线程占用。达到此目的的过程叫做同步(synchronization)。在某些情况中,您不必用同步来将数据从一个线程传递到另一个,因为JVM已经隐含地为您执行同步,如:由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时;访问final字段时;在创建线程之前创建对象时等线程同步概念Java实用编程技术与项目实战如果没有同步,数据很容易就处于不一致状态。例如,如果一个线程正在更新两个相关值(比如,粒子的位置和速率),而另一个线程正在读取这两个值,有可能在第一个线程只写了一个值,还没有写另一个值的时候,调度第二个线程运行,这样它就会看到一个旧值和一个新值。同步让我们可以定义必须原子地运行的代码块,这样对于其他线程而言,它们要么都执行,要么都不执行线程同步概念Java实用编程技术与项目实战同步的关键是管程(也叫信号量semaphore)的概念。管程是一个互斥独占锁定的对象,或称互斥体(mutex)。在给定的时间,仅有一个线程可以获得管程。当一个线程需要锁定,它必须进入管程。所有其他的试图进入已经锁定的管程的线程必须挂起直到第一个线程退出管程。这些其他的线程被称为等待管程。一个拥有管程的线程如果愿意的话可以再次进入相同的管程线程同步概念Java实用编程技术与项目实战Java中同步是简单的,因为所有对象都有它们与之对应的隐式管程。进入某一对象的管程,就是调用被synchronized关键字修饰的方法。当一个线程在一个同步方法内部,所有试图调用该方法(或其他同步方法)的同实例的其他线程必须等待。为了退出管程,并放弃对对象的控制权给其他等待的线程,拥有管程的线程仅需从同步方法中返回线程同步概念Java实用编程技术与项目实战classCallme{ voidcall(Stringmsg) { System.out.print("["+msg); try { Thread.sleep(1000); } catch(InterruptedExceptione) { System.out.println("Interrupted"); } System.out.println("]"); }}线程同步概念Java实用编程技术与项目实战classCallerimplementsRunnable{ Stringmsg; Callmetarget; Threadt; publicCaller(Callmetarg,Strings) { target=targ; msg=s; t=newThread(this); t.start(); }线程同步概念Java实用编程技术与项目实战classCallerimplementsRunnable{ Stringmsg; Callmetarget; Threadt; publicCaller(Callmetarg,Strings) { target=targ; msg=s; t=newThread(this); t.start(); }publicvoidrun() { target.call(msg); }}线程同步概念Java实用编程技术与项目实战publicclassTest{ publicstaticvoidmain(Stringargs[]) { Callmetarget=newCallme(); Callerob1=newCaller(target,"Hello"); Callerob2=newCaller(target,"Synchronized"); Callerob3=newCaller(target,"World"); try { ob1.t.join(); ob2.t.join(); ob3.t.join(); } catch(InterruptedExceptione) { System.out.println("Interrupted"); } }}线程同步概念Java实用编程技术与项目实战该程序的输出如下:[Hello[Synchronized[World]]]从输出看出,结果并非想要的那样。因为通过调用sleep(),call()方法允许执行转换到另一个线程。导致该结果是三个消息字符串的混合输出。如果能够限制三个线程同时调用同一对象的同一方法的方法,则可以按照期望的那样输出结果线程同步概念Java实用编程技术与项目实战为达到上例所想达到的目的,必须有权连续的使用call()。也就是说,在某一时刻,必须限制只有一个线程可以支配它。为此,你只需在call()定义前加上关键字synchronized,如下:synchronizedvoidcall(Stringmsg)线程同步概念Java实用编程技术与项目实战保证了在一个线程使用call()时其他线程进入call()。在synchronized加到call()前面以后,程序输出如下:[Hello][Synchronized][World]线程同步概念Java实用编程技术与项目实战前面的例子都无条件的阻塞了其他线程异步访问某个方法。多线程通过把任务分成离散的和合乎逻辑的单元代替了事件循环程序Java包含了通过wait(),notify()和notifyAll()方法实现的一个进程间通信机制wait()告知被调用的线程放弃管程进入睡眠直到其他线程进入相同管程并且调notify()。notify()恢复相同对象中第一个调用wait()的线程。notifyAll()恢复相同对象中所有调用wait()的线程。具有最高优先级的线程最先运行线程通信Java实用编程技术与项目实战下面的例子程序错误的实行了一个简单生产者/消费者的问题。它由四个类组成:Q(队列,模拟取数据、存数据);Producer(生产者线程对象);Consumer(消费者线程对象);以及主程序类线程通信Java实用编程技术与项目实战classQ{intn;booleanvalueSet=false;synchronizedintget(){

if(!valueSet)

try

{

wait();

}

catch(InterruptedExceptione)

{

System.out.println("InterruptedExceptioncaught");

}

System.out.println("Got:"+n);

valueSet=false;

notify();

returnn;}线程通信Java实用编程技术与项目实战synchronizedvoidput(intn){

if(valueSet)

try

{

wait();

}

catch(InterruptedExceptione)

{

System.out.println("InterruptedExceptioncaught");

}

this.n=n;

valueSet=true;

System.out.println("Put:"+n);

notify();}}线程通信Java实用编程技术与项目实战classProducerimplementsRunnable{Qq;

Producer(Qq){

this.q=q;

newThread(this,"Producer").start();}线程通信Java实用编程技术与项目实战publicvoidrun(){

inti=0;

while(true)

{

q.put(i++);

}}}classConsumerimplementsRunnable{Qq;

Consumer(Qq)

{

this.q=q;

newThread(this,"Consumer").start();}线程通信Java实用编程技术与项目实战publicvoidrun(){

while(true)

{

q.get();

}}}publicclassTest{publicstaticvoidmain(Stringargs[]){

Qq=newQ();

newProducer(q);

newConsumer(q);

System.out.println("PressControl-Ctostop.");}}线程通信Java实用编程技术与项目实战下面是该程序的输出,它清楚地显示了同步行为:Put:1Got:1Put:2Got:2Put:3Got:3Put:4Got:4Put:5Got:5

线程通信Java实用编程技术与项目实战网络编程技术是当前一种主流的编程技术,随着互联网趋势的逐步增强以及网络应用程序的大量出现,网络编程技术在实际的开发中获得了大量的使用。网络编程的实质就是两个(或多个)设备(例如计算机)之间的数据传输。TCP(TransmissionControlProtocol),指的是传输控制协议,它是主要负责数据的分组和重组。在简化的计算机网络OSI模型中,它完成第四层传输层所指定的功能TCP是一个“可靠的”、面向连结的传输机制,通过三次握手建立连接。它提供一种可靠的字节流保证数据完整、无损并且按顺序到达网络编程基础TCP协议Java实用编程技术与项目实战UDP(UserDatagramProtocol)指的是用户数据报协议。和TCP一样都是网络传输层上的协议,但与TCP有本质的区别UDP是“不可靠”、无连结和面向消息的协议,它使用数据报进行传输UDP协议Java实用编程技术与项目实战端口(Port)可以被理解成计算机与外界通信交流的窗户。网络上的一台计算机可以提供多种服务,单靠IP地址无法将它们区别开,所以通过“IP地址+端口号”的形式来区分不同的服务端口号是一个整数,通常范围在0~65535。小于1024的端口号一般的分配给特定的服务协议的端口Java实用编程技术与项目实战套接字,是支持TCP/IP的网络通信的基本操作单元,可以看成在两个程序进行通讯连接中的一个端点,是连接应用程序和网络驱动程序的桥梁,Socket在应用程序中创建,通过绑定与网络驱动建立关系通常用的TCP/IP协议的3种套接字类型有

流套接字(SOCK_STREAM)、数据报套接字(SOCK_DGRAM)、原始套接字(SOCK_RAW)流套接字用于提供面向连接、可靠的数据传输服务数据报套接字(SOCK_DGRAM):数据报套接字提供了一种无连接的服务原始套接字(SOCK_RAW):原始套接字可以读写内核没有处理的IP数据包套接字Java实用编程技术与项目实战C/S(Client/Server,客户机/服务器)模式又称C/S结构,是20世纪80年代末逐步成长起来的一种模式,是软件系统体系结构的一种C/S结构的关键在于功能的分布,一些功能放在前端机(即客户机)上执行,另一些功能放在后端机(即服务器)上执行在Berkeley套接字中,套接字的概念允许单个计算机同时服务于很多不同的客户,并能够提供不同类型信息的服务客户机/服务器的通信基于套结字。套结字是internet通信的端点。可以理解为是客户机和服务器之间的两端客户/服务器模式Java实用编程技术与项目实战客户程序创建客户套接字,服务器应用程序创建服务器套接字。双方的套接字连接起来后,数据通过这一连接来交换客户/服务器模式Java实用编程技术与项目实战Java通过扩展流式输入/输出接口和增加在网络上建立输入/输出对象特性这两个方法支持TCP/IPJava支持TCP和UDP协议族Java提供的网络功能有三大类:URL、Socket、DatagramTCP用于网络的可靠的流式输入/输出。UDP支持更简单的、快速的、点对点的数据报模式JAVA和网络Java实用编程技术与项目实战Authenticator(Java2)JarURLConnection(Java2)SocketPermissionContentHandlerMulticastSocketURLDatagramPacketNetPermissionURLClassLoader(Java2)DatagramSocketPasswordAuthentication(Java2)URLConnectionDatagramSocketImplServerSocketURLDecoder(Java2)HttpURLConnectionSocketURLEncoderInetAddressSocketImplURLStreamHandlerJAVA和网络Java实用编程技术与项目实战网络类包所包含的类ContentHandlerFactorySocketImplFactoryURLStreamHandlerFactoryFileNameMapSocketOptionsDatagramSocketImplFactoryJAVA和网络Java实用编程技术与项目实战包的接口InetAddress类用来封装数字式的IP地址和该地址的域名InetAddress类可以用于标识网络上的硬件资源,建立IP地址。把IP地址或是DomainName转换成电脑看得懂的网络地址InetAddress类没有明显的构造方法。为生成一个InetAddress对象,必须运用一个可用的工厂方法InetAddress类Java实用编程技术与项目实战方法名称方法说明publicBooleanequals(Objectobj)判断给定对象是否与当前对象拥有相同的IP地址,相同时,函数返回true,不同时,返回false。publicbyte[]getAddress()返回当前对象的IP地址publicstaticInetAddress[]getAllByName(Stringhost)throwsUnknownHostException返回给定主机名的资源所在的所有IP地址。publicstaticInetAddressgetByName(Stringhost)throwsUnknownHostException返回给定主机名的主机的IP地址。

InetAddress类Java实用编程技术与项目实战InetAddress类主要方法方法名称方法说明publicStringgetHostName()返回当前对象的主机名。publicstaticInetAddressgetLocalHost()throwsUnknownHostException返回本地主机的IP地址。publicinthashCode()返回当前对象的IP地址的散列码。publicStringtoString()返回当前对象的IP地址的字符串表示。

InetAddress类Java实用编程技术与项目实战InetAddress类主要方法import.*;publicclassTest{publicstaticvoidmain(Stringargs[])throwsUnknownHostException { InetAddressAddress=InetAddress.getLocalHost(); System.out.println(Address); Address=InetAddress.getByName(""); System.out.println(Address); InetAddressia[]=InetAddress.getAllByName("www."); for(inti=0;i<ia.length;i++) System.out.println(ia[i]); }}

InetAddress类Java实用编程技术与项目实战URL提供了一个相当容易理解的形式来惟一确定或对Internet上的信息进行编址在Java的网络类库中,URL类为用URL在Internet上获取信息提供了一个简单的、简洁的用户编程接口(API)URL规范以四个元素为基础:所用到的协议、主机名或所用主机的IP地址、端口号、实际的文件路径URLJava实用编程技术与项目实战方法名称方法说明publicURL(Stringaddr)throwsMalformedURLException创建一个给定资源地址的URL对象,这里,addr应是一个合法的URL值。publicURL(Stringprotocol,Stringhost,Stringfile)throwsMalformedURLException创建一个拥有指定协议名称、主机名、文件名的URL对象pubicURL(Stringprotocol,Stringhost,intport,Stringfile)throwsMaformedURLException创建一个拥有指定协议名称、主机名、端口号、文件名的URL对象publicStringgetProtocol()返回URL中的协议名称URLJava实用编程技术与项目实战URL类的主要方法方法名称方法说明publicStringgetHost()返回URL中的主机名publicintgetPort()返回URL中的端口号。如果URL中没有设定端口号,该函数返回-1。publicStringgetFile()返回URL中的文件名部分publicStringgetRef()返回URL的引用。publicStringtoString()返回整个URL值URLJava实用编程技术与项目实战URL类的主要方法import.*;publicclassTest{ publicstaticvoidmain(Stringargs[])throwsMalformedURLException { URLhp=newURL("/download"); System.out.println("Protocol:"+hp.getProtocol()); System.out.println("Port:"+hp.getPort()); System.out.println("Host:"+hp.getHost()); System.out.println("File:"+hp.getFile()); System.out.println("Ext:"+hp.toExternalForm()); }}URLJava实用编程技术与项目实战为获URL的实际比特或内容信息,用它的openConnection()方法从它创建一个URLConnection对象,如下常用形式:URLConnectionopenConnection()它返回一个URLConnection对象。它可能引发IOException异常URLJava实用编程技术与项目实战例:用URL对象的openConnection()方法创建了一个URLConnection类,然后用它来检查文件的属性和内容import.*;importjava.io.*;importjava.util.Date;publicclassTest{ publicstaticvoidmain(Stringargs[])throwsException { intc;URLhp=newURL("");URLConnectionhpCon=hp.openConnection();System.out.println("Date:"+newDate(hpCon.getDate()));System.out.println("Content-Type:"+hpCon.getContentType());URLJava实用编程技术与项目实战System.out.println("Expires:"+hpCon.getExpiration());System.out.println("Last-Modified:"+newDate(hpCon.getLastModified()));intlen=hpCon.getContentLength();System.out.println("Content-Length:"+len);if(len>0){System.out.println("Content:");InputStreaminput=hpCon.getInputStream();inti=len;while(((c=input.read())!=-1)&&(--i>0))System.out.print((char)c);input.close();}elseSystem.out.println("NoContentAvailable");}}URLJava实用编程技术与项目实战该程序建立了一个经过端口80通向的HTTP连接。然后列出了标头值并检索内容。下面是输出的前几行:Date:FriOct0622:11:12CDT2011Content-Type:text/htmlExpires:0Last-Modified:TueOct2811:16:27CDT2011Content-Length:529Content:<html><head><title>myweb</title></head>URLJava实用编程技术与项目实战TCP/IP套接字用于在主机和Internet之间建立可靠的、双向的、持续的、点对点的流式连接。一个套接字可以用来建立Java的输入/输出系统到其他的驻留在本地机或Internet上的任何机器的程序的连接。Java中有两类TCP套接字,一种是服务器端的,另一种是客户端的。Socket:客户端套接字类,为建立连向服务器套接字以及启动协议交换而设计。一个Socket对象的创建隐式建立了一个客户和服务器的连接。没有显式的说明建立连接细节的方法或构造方法。表3.7所示是用来生成客户套接字的两个构造方法。TCP编程模型Java实用编程技术与项目实战生成客户套接字的两个构造方法TCP编程模型方法含义Socket(StringhostName,intport)创建一个本地主机与给定名称的主机端口的套接字连接,可以引发一个UnknownHostException异常或IOException异常Socket(InetAddressipAddress,intport)用一个预先存在的InetAddress对象和端口创建一个套接字,可以引发IOException异常Java实用编程技术与项目实战方法含义InetAddressgetInetAddress()返回和Socket对象相关的InetAddressIntgetPort()返回与该Socket对象连接的远程端口IntgetLocalPort()返回与该Socket连接的本地端口TCP编程模型Java实用编程技术与项目实战地址与端口方法方法含义InputStreamgetInputStream()返回与调用套接字有关的InputStream类OutputStreamgetOutputStream()返回与调用套接字有关的OutputStream类voidclose()关闭InputStream和OutputStreamTCP编程模型Java实用编程技术与项目实战输入和输出流方法ServerSocket:服务器端套结字类,设计成在等待客户建立连接之前不做任何事的“监听器”ServerSocket与通常的Sockets类完全不同。当创建一个ServerSocket类,它在系统注册自己对客户连接感兴趣ServerSocket的构造方法反映了希望接收连接的端口号及希望排队等待上述端口的时间。队列长度告诉系统多少与之连接的客户在系统拒绝连接之前可以挂起。队列的默认长度是50TCP编程模型Java实用编程技术与项目实战方法含义ServerSocket(intport)在指定端口创建队列长度为50的服务器套接字ServerSocket(intport,intmaxQueue)在指定端口创建一个最大队列长度为maxQueue的服务器套接字ServerSocket(intport,intmaxQueue,InetAddresslocalAddress)在指定端口创建一个最大队列长度为maxQueue的服务器套接字。在一个多地址主机上,localAddress指定该套接字约束的IP地址TCP编程模型Java实用编程技术与项目实战服务器套接字类构造方法TCP编程模型Java实用编程技术与项目实战服务器端程序实现在端口8080上监听提供服务,从客户端读入数据后再向客户端发送信息客户端发送数据后再接收服务器数据该实例简单地实现两者的通信TCP编程模型Java实用编程技术与项目实战import.*;importjava.io.*;publicclassServer //服务器端程序{publicstaticvoidmain(String[]args){try{ServerSocketss=newServerSocket(8080);//创建ServerSocket对象,端口为8080while(true){Socketsocket=ss.accept(); //接收客户端请求//监听客户端的请求,等待连接,连接完成返回socket套接字TCP编程模型Java实用编程技术与项目实战InputStreamin=socket.getInputStream(); //定义输入流对象OutputStreamout=socket.getOutputStream(); //定义输出流对象InputStreamReaderreader=newInputStreamReader(in);BufferedReaderbufReader=newBufferedReader(reader);StringreadLine=bufReader.readLine();//读入一行System.out.println(readLine);PrintStreamps=newPrintStream(out);ps.print("Hello"); //输出信息ps.flush();bufReader.close();ps.close();ss.close();}}catch(Exceptione){System.out.println("Error");}}}TCP编程模型Java实用编程技术与项目实战import.*;importjava.io.*;publicclassClient //客户端程序{

publicstaticvoidmain(String[]args)throwsUnknownHostException,IOException{try{Socketsocket=newSocket("localhost",8080);//在本地机的8080端口创建socket对象DataInputStreamdis=newDataInputStream(newBufferedInputStream(socket.getInputStream())); //准备接收服务器端信息DataOutputStreamdos=newDataOutputStream(newBufferedOutputStream(socket.getOutputStream())); //准备发送数据对象TCP编程模型Java实用编程技术与项目实战dos.writeUTF("HelloServer!"); //发送数据dos.flush(); System.out.println(dis.readUTF());dis.close();dos.close();socket.close();}catch(Exceptione){System.out.println("Error");}}}TCP编程模型Java实用编程技术与项目实战对于现在的大多数网络需求,TCP/IP型网络已经基本可以满足其网络需求了。TCP包含很多在拥挤的网络中处理拥塞控制的复杂算法以及信息丢失的悲观的预测。这导致了一个效率很差的传输数据方式数据报(Datagrams)是在机器间传递的信息包,一旦数据报被释放给它们预定的目标,不保证它们一定到达目的地,甚至不保证一定存在数据的接收者。同样,数据报被接受时,不保证它在传输过程不受损坏,不保证发送它的机器仍在那儿等待响应UDP编程模型Java实用编程技术与项目实战Java通过两个类实现UDP协议顶层的数据报DatagramPacket类:创建一个用于发送的数据报,当接收数据UDP数据报时,可以使用DatagramPacket类读取数据报中的数据,发送者和其他消息DatagramSocket类:封装了套结字的有关信息和操作发送端,是用来发送和接受DatagramPackets的机制UDP编程模型Java实用编程技术与项目实战DatagramSocket类构造方法publicDatagramSocket()throwsExcetpionpublicDatagramSocket(intport)throwsExceptionDatagramSocket()方法创建一个负责发数据报的DatagramSocket类对象,DatagramSocket(intport)创建一个指定了端口号的DatagramSocket类对象。UDP编程模型Java实用编程技术与项目实战DatagramPackets可以用四个构造方法DatagramPacket(bytedata[],intsize)DatagramPacket(bytedata[],intoffset,intsize)DatagramPacket(bytedata[],intsize,InetAddressipAddress,intport)DatagramPacket(bytedata[],intoffset,intsize,InetAddressipAddress,intport)UDP编程模型Java实用编程技术与项目实战

DatagramPacket方法UDP编程模型方法含义InetAddressgetAddress()返回目标文件InetAddress,一般用于发送IntgetPort()返回端口号byte[]getData()返回包含在数据包中的字节数组数据。多用

温馨提示

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

评论

0/150

提交评论