一起学习,管道流满搞的,用着比socket的stream麻烦
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.*;
import java.nio.channels.*;
import java.nio.*;
import java.util.*;
import java.nio.charset.*;
public class TCP extends Thread{
private SocketChannel channel;
private ServerSocket serverSocket;
private ServerSocketChannel serverSocketChannel;
private ByteBuffer readBuffer;
private ByteBuffer sendBuffer;
private Boolean isAccept=false;
private boolean isConnect=false;
private Thread accept;
private Thread connect;
/** Creates a new instance of TCP */
public TCP(int port,String addr) {
try {
readBuffer=ByteBuffer.allocate(1024);
serverSocketChannel=ServerSocketChannel.open();
serverSocket=serverSocketChannel.socket();
serverSocket.setReuseAddress(true);
serverSocket.bind(new InetSocketAddress(port));
channel=SocketChannel.open();
channel.connect(new InetSocketAddress(InetAddress.getByName(addr),port));
accept=new Thread(){
public void run(){
Selector selector;
try {
selector=Selector.open();
serverSocketChannel.configureBlocking(false);
serverSocketChannel.register(selector,SelectionKey.OP_ACCEPT);
isAccept=false;
selectors(selector);
} catch (ClosedChannelException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
};
connect=new Thread(){
public void run(){
try{
Selector selector;
selector=Selector.open();
channel.configureBlocking(false);
channel.register(selector,SelectionKey.OP_WRITE|SelectionKey.OP_READ);
isConnect=false;
selectors(selector);
}catch (Exception ex){
ex.printStackTrace();
}
}
};
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("d1");
}catch(Exception ex){
System.out.println("d2");
}
}
private void service(){
if(isConnect){
connect.start();
}
if(isAccept){
accept.start();
}
}
private void selectors(Selector selector){
try {
while (selector.select()>0){
Set readyKeys=selector.selectedKeys();
Iterator<SelectionKey> it=readyKeys.iterator();
while(it.hasNext()){
SelectionKey key=null;
key=it.next();
it.remove();
if(key.isAcceptable()){
//System.out.println("isAcceptable");
ServerSocketChannel ssc=(ServerSocketChannel)key.channel();
SocketChannel socketChannel=ssc.accept();
socketChannel.configureBlocking(false);
socketChannel.register(selector,SelectionKey.OP_READ|SelectionKey.OP_WRITE);
}
if(key.isReadable()){
synchronized(readBuffer){
// System.out.println("isReadable");
ByteBuffer buffer=ByteBuffer.allocate(1024);
SocketChannel socketChannel=(SocketChannel)key.channel();
socketChannel.read(buffer);
readBuffer=buffer;
}
}
if(key.isWritable()){
synchronized(sendBuffer){
// System.out.println("isWritable");
SocketChannel channel=(SocketChannel)key.channel();
if(sendBuffer!=null)
channel.write(sendBuffer);
}
}
}
try {
sleep(1);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
} catch (ClosedChannelException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
public void send(ByteBuffer buff){
this.sendBuffer=buff;
}
public ByteBuffer get(){
return readBuffer;
}
public void accpet(){
isAccept=true;
}
public void connect(){
isConnect=true;
}
public void run(){
while (true){
service();
}
}
}
Ⅱ 求java nio网络编程的小例子,要求客户端一直与服务器保持连接
import java.awt.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import java.io.*;
public class chatClient extends Frame {
/**
* @param args
*/
TextField tfTxT=new TextField();
TextArea taContent=new TextArea();
Socket s=null;
DataOutputStream dos=null;
DataInputStream dis=null;
private boolean bConnected =false;
public static void main(String[] args) {
new chatClient().lunachFrame();
}
private class RecvThread implements Runnable{
public void run() {
try{
while(bConnected){
String str=dis.readUTF();
taContent.setText(taContent.getText()+str+'\n');
}
}catch(IOException e){
e.printStackTrace();
}
}
}
public void lunachFrame(){
this.setLocation(400, 300);
this.setSize(300,300);
//this.setLayout(new FlowLayout());
this.add(tfTxT,"South");
this.add(taContent,"North");
pack();
tfTxT.addActionListener(new TFListener());
this.addWindowListener(new WindowClose());
this.setVisible(true);
connect();
new Thread(new RecvThread()).start();
}
public void connect(){
try {
s= new Socket("127.0.0.1",8888);
dos =new DataOutputStream(s.getOutputStream());
dis =new DataInputStream(s.getInputStream());
System.out.println("connected!");
bConnected=true;
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void disconnect(){
try {
dos.close();
s.close();
} catch (Exception e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
class WindowClose extends WindowAdapter{
@Override
public void windowClosing(WindowEvent e) {
// TODO 自动生成方法存根
System.exit(0);
disconnect();
}
}
private class TFListener implements ActionListener{
public void actionPerformed(ActionEvent e) {
String str=tfTxT.getText().trim();//trim去掉两边空格
//taContent.setText(str);
tfTxT.setText("");
try {
dos.writeUTF(str);
dos.flush();
//dos.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
======================================
import java.io.IOException;
import java.net.*;
import java.io.*;
import java.util.*;
public class ChatServer {
List<Client> clients=new ArrayList<Client>();
Client c=null;
public static void main(String[] args){
new ChatServer().start();
}
public void start(){
boolean started=false;
ServerSocket ss=null;
DataInputStream dis=null;
try{
ss=new ServerSocket(8888);
started =true;
}catch(Exception e)
{
e.printStackTrace();
}
try{
while(started){
Socket s=ss.accept();
c=new Client(s);//启动线程,实行run()方法
System.out.println("a client connected!");
new Thread(c).start();//启动start方法,循环.start是Thread中的方法与这上面的start无关
clients.add(c);
//dis.close();
}
} catch (Exception e) {
//e.printStackTrace();
}
finally{
try {
ss.close();
} catch (IOException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
}
class Client implements Runnable{
private Socket s;
private DataInputStream dis =null;
private boolean bConnected =false;
private DataOutputStream dos=null;
public Client(Socket s){
this.s=s;
try {
dis=new DataInputStream(s.getInputStream());
dos =new DataOutputStream(s.getOutputStream());
bConnected =true;
} catch (IOException e) {
// TODO 自动生成 catch 块
e.printStackTrace();
}
}
public void send(String str)throws Exception{
dos.writeUTF(str);
}
public void run() {
try{
while(bConnected){
String str = dis.readUTF();
System.out.println(str);
for(int i=0;i<clients.size();i++){
c=clients.get(i);
c.send(str);
}
/*for(Iterator<Client> it=clients.iterator();it.hasNext();){
Client c=it.next();
c.send(str);
}*/
}
}catch(SocketException e){
clients.remove(this);
System.out.println("客户下线了");
}
catch(EOFException e){
System.out.println("Client closed");
}
catch (Exception e){
//e.printStackTrace();
}
finally{
try {
if(dis !=null) dis.close();
if(dos !=null) dos.close();
if(s!=null) s.close();
} catch (Exception e1) {
// TODO 自动生成 catch 块
//e1.printStackTrace();
}
}
}
}
}
第一个是客户端,
第二个是server端
Ⅲ java Nio读写为什么是双向
作者:美团技术团队
链接:https://zhuanlan.hu.com/p/23488863
来源:知乎
着作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
NIO(Non-blocking I/O,在Java领域,也称为New I/O),是一种同步非阻塞的I/O模型,也是I/O多路复用的基础,已经被越来越多地应用到大型应用服务器,成为解决高并发与大量连接、I/O处理问题的有效方式。
那么NIO的本质是什么样的呢?它是怎样与事件模型结合来解放线程、提高系统吞吐的呢?
本文会从传统的阻塞I/O和线程池模型面临的问题讲起,然后对比几种常见I/O模型,一步步分析NIO怎么利用事件模型处理I/O,解决线程池瓶颈处理海量连接,包括利用面向事件的方式编写服务端/客户端程序。最后延展到一些高级主题,如Reactor与Proactor模型的对比、Selector的唤醒、Buffer的选择等。
注:本文的代码都是伪代码,主要是为了示意,不可用于生产环境。
传统BIO模型分析
让我们先回忆一下传统的服务器端同步阻塞I/O处理(也就是BIO,Blocking I/O)的经典编程模型:
{
ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//线程池
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(8088);
while(!Thread.currentThread.isInturrupted()){//主线程死循环等待新连接到来
Socket socket = serverSocket.accept();
executor.submit(new ConnectIOnHandler(socket));//为新的连接创建新的线程
}
class ConnectIOnHandler extends Thread{
private Socket socket;
public ConnectIOnHandler(Socket socket){
this.socket = socket;
}
public void run(){
while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循环处理读写事件
String someThing = socket.read()....//读取数据
if(someThing!=null){
......//处理数据
socket.write()....//写数据
}
}
}
}
这是一个经典的每连接每线程的模型,之所以使用多线程,主要原因在于socket.accept()、socket.read()、socket.write()三个主要函数都是同步阻塞的,当一个连接在处理I/O的时候,系统是阻塞的,如果是单线程的话必然就挂死在那里;但CPU是被释放出来的,开启多线程,就可以让CPU去处理更多的事情。其实这也是所有使用多线程的本质:
利用多核。
当I/O阻塞系统,但CPU空闲的时候,可以利用多线程使用CPU资源。
现在的多线程一般都使用线程池,可以让线程的创建和回收成本相对较低。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的I/O并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。
不过,这个模型最本质的问题在于,严重依赖于线程。但线程是很"贵"的资源,主要表现在:
线程的创建和销毁成本很高,在Linux这样的操作系统中,线程本质上就是一个进程。创建和销毁都是重量级的系统函数。
线程本身占用较大内存,像Java的线程栈,一般至少分配512K~1M的空间,如果系统中的线程数过千,恐怕整个JVM的内存都会被吃掉一半。
线程的切换成本是很高的。操作系统发生线程切换的时候,需要保留线程的上下文,然后执行系统调用。如果线程数过高,可能执行线程切换的时间甚至会大于线程执行的时间,这时候带来的表现往往是系统load偏高、CPU sy使用率特别高(超过20%以上),导致系统几乎陷入不可用的状态。
容易造成锯齿状的系统负载。因为系统负载是用活动线程数或CPU核心数,一旦线程数量高但外部网络环境不是很稳定,就很容易造成大量请求的结果同时返回,激活大量阻塞线程从而使系统负载压力过大。
所以,当面对十万甚至百万级连接的时候,传统的BIO模型是无能为力的。随着移动端应用的兴起和各种网络游戏的盛行,百万级长连接日趋普遍,此时,必然需要一种更高效的I/O处理模型。
NIO是怎么工作的
很多刚接触NIO的人,第一眼看到的就是Java相对晦涩的API,比如:Channel,Selector,Socket什么的;然后就是一坨上百行的代码来演示NIO的服务端Demo……瞬间头大有没有?
我们不管这些,抛开现象看本质,先分析下NIO是怎么工作的。
常见I/O模型对比
所有的系统I/O都分为两个阶段:等待就绪和操作。举例来说,读函数,分为等待系统可读和真正的读;同理,写函数分为等待网卡可以写和真正的写。
需要说明的是等待就绪的阻塞是不使用CPU的,是在“空等”;而真正的读写操作的阻塞是使用CPU的,真正在"干活",而且这个过程非常快,属于memory ,带宽通常在1GB/s级别以上,可以理解为基本不耗时。
下图是几种常见I/O模型的对比:
密码:380p以上都是小编收集了大神的灵药,喜欢的拿走吧!喜欢小编就轻轻关注一下吧!
Ⅳ 针对Java 网络编程,有哪些比较好的书推荐
Java 网络编程,比较好的书:
ava TCPIP Socket编程(中文版) Java NIO (中文版) 中文的好理解
java 7 出了AIO 你有必要去网络了解下
Ⅳ java里面的NIO是什么,有什么用
NIO即New IO,这个库是在JDK1.4中才引入的。NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多。
在Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
Ⅵ JAVA开发工程师必须懂什么
java Netty实战课程java高性能分布式RPC教程课程 免费下载
链接:https://pan..com/s/1MpUM62h4nvHnUGMan-R6YA
Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程
Ⅶ Java网络编程精解的目录
第1章 Java网络编程入门 1
1.1 进程之间的通信 1
1.2 计算机网络的概念 3
1.3 OSI参考模型 5
1.4 TCP/IP参考模型和TCP/IP协议 8
1.4.1 IP协议 11
1.4.2 TCP协议及端口 14
1.4.3 RFC简介 15
1.4.4 客户/服务器通信模式 16
1.5 用Java编写客户/服务器程序 17
1.5.1 创建EchoServer 18
1.5.2 创建EchoClient 20
1.6 小结 22
1.7 练习题 23
第2章 Socket用法详解 25
2.1 构造Socket 25
2.1.1 设定等待建立连接的超时时间 26
2.1.2 设定服务器的地址 26
2.1.3 设定客户端的地址 27
2.1.4 客户连接服务器时可能抛出的异常 27
2.2 获取Socket的信息 30
2.3 关闭Socket 32
2.4 半关闭Socket 33
2.5 设置Socket的选项 38
2.5.1 TCP_NODELAY选项 38
2.5.2 SO_RESUSEADDR选项 38
2.5.3 SO_TIMEOUT选项 39
2.5.4 SO_LINGER选项 42
2.5.5 SO_RCVBUF选项 44
2.5.6 SO_SNDBUF选项 45
2.5.7 SO_KEEPALIVE选项 45
2.5.8 OOBINLINE选项 45
2.5.9 服务类型选项 45
2.5.10 设定连接时间、延迟和带宽的相对重要性 46
2.6 发送邮件的SMTP客户程序 47
2.7 小结 51
2.8 练习题 52
第3章 ServerSocket用法详解 55
3.1 构造ServerSocket 55
3.1.1 绑定端口 55
3.1.2 设定客户连接请求队列的长度 56
3.1.3 设定绑定的IP地址 58
3.1.4 默认构造方法的作用 58
3.2 接收和关闭与客户的连接 59
3.3 关闭ServerSocket 60
3.4 获取ServerSocket的信息 60
3.5 ServerSocket选项 62
3.5.1 SO_TIMEOUT选项 62
3.5.2 SO_REUSEADDR选项 63
3.5.3 SO_RCVBUF选项 64
3.5.4 设定连接时间、延迟和带宽的相对重要性 64
3.6 创建多线程的服务器 65
3.6.1 为每个客户分配一个线程 65
3.6.2 创建线程池 67
3.6.3 使用JDK类库提供的线程池 72
3.6.4 使用线程池的注意事项 74
3.7 关闭服务器 76
3.8 小结 80
3.9 练习题 81
第4章 非阻塞通信 83
4.1 线程阻塞的概念 83
4.1.1 线程阻塞的原因 83
4.1.2 服务器程序用多线程处理阻塞通信的局限 84
4.1.3 非阻塞通信的基本思想 85
4.2 java.nio包中的主要类 87
4.2.1 缓冲区Buffer 88
4.2.2 字符编码Charset 90
4.2.3 通道Channel 90
4.2.4 SelectableChannel类 92
4.2.5 ServerSocketChannel类 93
4.2.6 SocketChannel类 93
4.2.7 Selector类 96
4.2.8 SelectionKey类 97
4.3 服务器编程范例 100
4.3.1 创建阻塞的EchoServer 100
4.3.2 创建非阻塞的EchoServer 103
4.3.3 在EchoServer中混合用阻塞模式与非阻塞模式 110
4.4 客户端编程范例 114
4.4.1 创建阻塞的EchoClient 114
4.4.2 创建非阻塞的EchoClient 116
4.4.3 创建非阻塞的PingClient 120
4.5 小结 126
4.6 练习题 127
第5章 创建非阻塞的HTTP服务器 129
5.1 HTTP协议简介 129
5.1.1 HTTP请求格式 129
5.1.2 HTTP响应格式 132
5.1.3 测试HTTP请求 133
5.2 创建非阻塞的HTTP服务器 137
5.2.1 服务器主程序:
HttpServer类 137
5.2.2 具有自动增长的缓冲区的ChannelIO类 138
5.2.3 负责处理各种事件的
Handler接口 140
5.2.4 负责处理接收连接就绪
事件的AcceptHandler类 140
5.2.5 负责接收HTTP请求和发送HTTP响应的RequestHandler类 141
5.2.6 代表HTTP请求的Request类 143
5.2.7 代表HTTP响应的Response类 145
5.2.8 代表响应正文的Content接口及其实现类 147
5.2.9 运行HTTP服务器 149
5.3 小结 150
5.4 练习题 151
第6章 客户端协议处理框架 153
6.1 客户端协议处理框架的主要类 153
6.2 在客户程序中运用协议处理框架 154
6.2.1 URL类的用法 154
6.2.2 URLConnection类的用法 156
6.3 实现协议处理框架 160
6.3.1 创建EchoURLConnection类 161
6.3.2 创建EchoURLStreamHandler及工厂类 162
6.3.3 创建EchoContentHandler类及工厂类 163
6.3.4 在EchoClient类中运用ECHO协议处理框架 165
6.4 小结 166
6.5 练习题 167
第7章 用Swing组件展示HTML文档 169
7.1 在按钮等组件上展示HTML文档 170
7.2 用JEditorPane组件创建简单的浏览器 171
7.3 小结 179
7.4 练习题 179
第8章 基于UDP的
数据报和套接字 181
8.1 UDP协议简介 181
8.2 DatagramPacket类 184
8.2.1 选择数据报的大小 185
8.2.2 读取和设置DatagramPacket的属性 185
8.2.3 数据格式的转换 186
8.2.4 重用DatagramPacket 187
8.3 DatagramSocket类 189
8.3.1 构造DatagramSocket 189
8.3.2 接收和发送数据报 190
8.3.3 管理连接 190
8.3.4 关闭DatagramSocket 191
8.3.5 DatagramSocket的选项 191
8.3.6 IP服务类型选项 193
8.4 DatagramChannel类 193
8.4.1 创建DatagramChannel 194
8.4.2 管理连接 194
8.4.3 用send()方法发送数据报 194
8.4.4 用receive()方法接收数据报 195
8.4.5 用write()方法发送数据报 198
8.4.6 用read()方法接收数据报 199
8.5 组播Socket 202
8.5.1 MulticastSocket类 205
8.5.2 组播Socket的范例 207
8.6 小结 209
8.7 练习题 210
第9章 对象的序列化与反序列化 213
9.1 JDK类库中的序列化API 213
9.2 实现Serializable接口 218
9.2.1 序列化对象图 220
9.2.2 控制序列化的行为 222
9.2.3 readResolve()方法在单例类中的运用 229
9.3 实现Externalizable接口 231
9.4 可序列化类的不同版本的序列化兼容性 233
9.5 小结 235
9.6 练习题 236
第10章 Java语言的反射机制 239
10.1 Java Reflection API简介 239
10.2 在远程方法调用中运用反射机制 244
10.3 代理模式 248
10.3.1 静态代理类 248
10.3.2 动态代理类 250
10.3.3 在远程方法调用中
运用代理类 253
10.4 小结 258
10.5 练习题 259
第11章 RMI框架 261
11.1 RMI的基本原理 262
11.2 创建第一个RMI应用 264
11.2.1 创建远程接口 264
11.2.2 创建远程类 265
11.2.3 创建服务器程序 267
11.2.4 创建客户程序 269
11.2.5 运行RMI应用 270
11.3 远程对象工厂设计模式 272
11.4 远程方法中的参数与返回值传递 277
11.5 回调客户端的远程对象 281
11.6 远程对象的并发访问 286
11.7 分布式垃圾收集 289
11.8 远程对象的equals()、hashCode()和clone()方法 294
11.9 使用安全管理器 294
11.10 RMI应用的部署及类的动态加载 295
11.11 远程激活 297
11.12 小结 303
11.13 练习题 304
第12章 通过JDBC API访问数据库 305
12.1 JDBC的实现原理 306
12.2 安装和配置MySQL数据库 308
12.3 JDBC API简介 310
12.4 JDBC API的基本用法 314
12.4.1 处理字符编码的转换 317
12.4.2 把连接数据库的各种属性放在配置文件中 318
12.4.3 管理Connection、Statement和ResultSet对象的生命周期 321
12.4.4 执行SQL脚本文件 326
12.4.5 处理SQLException 328
12.4.6 输出JDBC日志 329
12.4.7 获得新插入记录的主键值 329
12.4.8 设置批量抓取属性 330
12.4.9 检测驱动器使用的JDBC版本 330
12.4.10 元数据 331
12.5 可滚动及可更新的结果集 333
12.6 行集 339
12.7 调用存储过程 346
12.8 处理Blob和Clob类型数据 347
12.9 控制事务 351
12.9.1 事务的概念 351
12.9.2 声明事务边界的概念 353
12.9.3 在mysql.exe程序中声明事务 354
12.9.4 通过JDBC API声明事务边界 356
12.9.5 保存点 357
12.9.6 批量更新 358
12.9.7 设置事务隔离级别 360
12.10 数据库连接池 362
12.10.1 创建连接池 363
12.10.2 DataSource数据源 369
12.11 小结 371
12.12 练习题 372
第13章 基于MVC和RMI的分布式应用 375
13.1 MVC设计模式简介 375
13.2 store应用简介 377
13.3 创建视图 381
13.4 创建控制器 389
13.5 创建模型 390
13.6 创建独立应用 394
13.7 创建分布式应用 395
13.8 小结 398
13.9 练习题 398
第14章 通过JavaMail API收发邮件 401
14.1 E-mail协议简介 401
14.1.1 SMTP简单邮件传输协议 401
14.1.2 POP3邮局协议 402
14.1.3 接收邮件的新协议IMAP 402
14.1.4 MIME简介 403
14.2 JavaMail API简介 403
14.3 建立JavaMail应用程序的开发环境 405
14.3.1 获得JavaMail API的类库 405
14.3.2 安装和配置邮件服务器 406
14.4 创建JavaMail应用程序 408
14.5 身份验证 412
14.6 URLName类 416
14.7 创建和读取复杂电子邮件 418
14.7.1 邮件地址 419
14.7.2 邮件头部 420
14.7.3 邮件标记 421
14.7.4 邮件正文 422
14.8 操纵邮件夹 427
14.9 小结 432
14.10 练习题 433
第15章 安全网络通信 435
15.1 SSL简介 435
15.1.1 加密通信 436
15.1.2 安全证书 436
15.1.3 SSL握手 437
15.1.4 创建自我签名的安全证书 438
15.2 JSSE简介 439
15.2.1 KeyStore、KeyManager与TrustManager类 442
15.2.2 SSLContext类 443
15.2.3 SSLServerSocketFactory类 444
15.2.4 SSLSocketFactory类 444
15.2.5 SSLSocket类 444
15.2.6 SSLServerSocket类 447
15.2.7 SSLEngine类 448
15.3 创建基于SSL的安全服务器和安全客户 453
15.4 小结 457
15.5 练习题 457
第16章 CORBA简介 459
16.1 创建IDL接口 460
16.2 创建IDL接口的实现类 460
16.3 创建服务器程序 461
16.4 创建客户程序 462
16.5 运行CORBA程序 463
16.6 小结 464
16.7 练习题 465
第17章 Web服务简介 467
17.1 SOAP简介 467
17.2 建立Apache AXIS环境 469
17.3 在Tomcat上发布
Apache-AXIS Web应用 470
17.4 创建SOAP服务 471
17.4.1 创建提供SOAP
服务的Java类 471
17.4.2 创建SOAP服务的
发布描述符文件 471
17.5 管理SOAP服务 472
17.5.1 发布SOAP服务 472
17.5.2 删除SOAP服务 473
17.6 创建和运行SOAP
客户程序 473
17.7 发布JWS服务 476
17.8 小结 476
17.9 练习题 477
附录A 本书范例的运行方法 479
A.1 本书所用软件的下载地址 479
A.2 部分软件的安装 479
A.2.1 安装JDK 480
A.2.2 安装ANT 480
A.2.3 安装Tomcat 481
A.3 编译源程序 481
A.4 运行客户/服务器程序 482
Ⅷ java常用api有哪些
Java常用API包括如下:
Java集合(位于java.util包下)
Java数据库编程zhuan(位于java.sql和javax.sql包行下shu),
Java输入输出(位于java.io和java.nio包下),
Java图形界面编程(位于java.awt包和javax.swing包下),
Java国际化和格式化(位于java.text包下),
Java多线程编程(位于java.concurrent包下),
Java网络编程编程(位于java.net包下)