java/android网络编程

        java的网络编程基本适合android,android在java网络编程的基础上进行扩展。使用这种模式进行网络编程的掌握。

        对于java有其自身的网络编程体系,我们从这个体系模块对于网络编程进行简洁记忆。


        实际上网络编程分为两条路:1、Socket与C/S的网络编程。2、URLConnection与URL的网络编程。其他的都是以他们为基础进行扩展得到的。这其中涉及到的,如远程过程调用RPC,远程方法调用RMI(所使用的类在java.rmi,javax.rmi包里),JMS是java消息服务,SOAP简单对象访问协议等编程都是扩展之后得到的。


        java网络编程的基础是Socket,ServerSocket。又由于阻塞,异步性能的需求,在此基础上扩展出SocketChannel,ServerSocketChannel。但是他们是属于不同的体系的,Socket,ServerSocket是属于java.net包的。而SocketChannel,ServerSocketChannel则是属于java.nio包的。另外还有android.net包可以实现网络编程。


        对于Socket,ServerSocket编程,我们需要另外在开一个线程,同时还要考虑阻塞问题,异步问题。这些是非常需要注意的。


        对于SocketChannel,ServerSocketChannel其实更多的是在于IO的角度进行的网络编程,因为他是为了弥补Socket,ServerSocket性能上的不足,简化常见的编程步骤才被开发出来的。可以说这是站在IO角度进行网络编程的类。


        其实如果单单就掌握网络编程的话,就只是使用Socket,ServerSocket与SocketChannel,ServerSocketChannel进行编程就可以了(最纯粹的网络编程使用的是Socket,ServerSocket进行的编程)。其他的扩展将会在以后有需要时进行扩展学习,因为扩展的那些已经不仅仅是网络编程了,更多的是由网络编程扩展出的新功能,如RMI,进行远程方法的调用。


        在说 SocketChannel,ServerSocketChannel之前必须先说一说ByteBuffer,因为 SocketChannel,ServerSocketChannel使用的是ByteBuffer进行的数据传递。Buffer的所有子类都是非线程安全的(线程安全指的是其实有多个线程运行,但是最后运行的结果和单线程运行的结果是一样的,就是说不用考虑同步问题),ByteBuffer使用put()以及get()进行基本的数据操作,同时提供了putxx(),getxx()方法进行相关数据的读写操作,但是都是基于读写单个基本数据类型数据进行的,读取数组可使用array(),get(byte[])进行,同时对ByteBuffer进行实例化的时候,使用wrap()最能有效的利用资源,使用allocate()则是指定空间大小。


注意区分同步,异步,线程安全,非线程安全,阻塞,非阻塞的概念。线程安全是由全局变量,静态变量引入的,如果对他们进行读操作,则不会有问题,但是如果进行写操作,则有可能出现二义性,即一个对象出现不同结果而不知道要使用那个结果。同步,异步是相对于是否需要共同的时钟而言的,同步需要,异步不需要,简单点说就是同步执行访问时需要得到确认返回才能往下执行,即未得到返回时阻塞。而异步则不需要,异步请求发出后直接往下执行,即未得到返回也不阻塞。其实同步,异步的“步”指的是步调,同步就是同步调,异步则是不同步调(其实电脑同时就只能做一件事情而已,只是由于时间短,而且又是轮流着做的,所以看起来就像是同时做很多件事情)。对于阻塞,其实就是当执行某一程序时,其他程序不能执行,而非阻塞则可以。



        SocketChannel,ServerSocketChannel使用,Channel是父类接口,后面产生的重要子类有SelectableChannel,然后是AbstractSelectableChannel,然后产生重要子类,也就是我们现在讨论的SocketChannel,ServerSocketChannel。使用SelectionKey.channel()就可以得到SlectableChannel抽象类。SelectableChannel封装有SocketChannel,ServerSocketChannel的基本操作方法,所以我们在得到SelectableChannel后一般都使用强制转换将SelectableChannel转换为ServerSocketChannel,然后进行相关操作。

        其实SocketChannel,ServerSocketChannel的网络编程中最重要的是Selector与SelectionKey这两个类。ServerSocketChannel.register(Selector,SlectionKey.op_xx)作用是向Selector注册,其二个参数作用是设置权限,有4个重要权限,分别是SelectionKey.OP_ACCEPT,SelectionKey.OP_CONNECT,SelectionKey.READ,SelectionKey.WRITE,一般设置为第一个,即Selector要处理的是接受传入事件。

        Channel接口所在的体系模块定义了文件系统和网络通讯的相关操作类,这个包还定义了Selector,SelectableChannel两个很有用的类。非阻塞IO使程序可以同时监控多个channel,这一功能是通过Selector,SelectableChannel,SelectionKey实现的。其中SelectableChannel代表了可以进行非阻塞IO操作的channel,可以将其注册在Selector上,注册的关系由SelectionKey来表现。Selector通过方法select()提供给程序一个可以同时监控多个IO Channel的方法,通过select()程序检查注册到selector上的各个SelectableChannel的状态,有channel的IO操作返回时,select()就会返回让程序检查channel的状态,并作出相应的处理。简单点说就是,SelectableChannel.register(Selector,SelectionKey.xx),然后使用int num=Selector.select()得到相应的状态以进行处理。这里返回的状态其实是代表了有多少channel可以进行处理。同时注意,每一个SelectionKey代表了一个可以进行处理的channel,同时使用SelectionKey.channel()得到的channel代表了有一个TCP连接连入。

        这里ServerSocketChannel c=(ServerSocketChannel)SelectionKey.channel(),然后使用SocketChannel channel=c.accept()可以得到SocketChannel,这一步才是真正的TCP的连接接入,同时使用Socket socket=channel.socket()可以得到Socket,这是就可以进行真正的IO操作了。同时还要注意一点,就是每一个SelectionKey用完之后记得移除,否则占用资源,同时记得关闭socket的IO连接。

        对于网络编程最关键的还是设计的时候所涉及到的线程安全,异步,非阻塞功能的实现,这是实际的编程中必不可少的功能,因此在实现了Socket,ServerSocket,ServerSocketChannel,SocketChannel之后必须要完成的任务就在于实现这些功能上。

        对于ServerSocketChannel,SocketChannel已经实现了非阻塞,异步功能。使用configureBlocking(false)可以实现非阻塞(其实在Channel最初实现的时候都是阻塞的)。异步功能则是通过Selector实现的,当有相应的事件产生时,Selector会监听到,这时会通知相应的SelectionKey中的Channel,然后Channel会使用ByteBuffer进行相应的IO操作。同时SocketChannel,ServerSocketChannel是线程安全的,尽管Socket是非线程安全的,因为Socket是面向流的,而非包导向的。同时注意SocketChannel,ServerSocketChannel中的connect(),finishConnect()都是同步的,就是说当有他们中的任意一个在执行时,其他的读写操作都是无法进行的。其实对于实现异步有三种方法分别是状态,回调,通知进行实现。这里使用的是通知进行异步的实现,同时也实现了非阻塞。而对于线程安全的实现则是需要参与操作Channel数据的线程只有一个,简单点说就是使用SelectionKey.cancel()取消Selector中的注册的SelectionKey的监视,防止多线程获取到SelectionKey的事件。实际上SelectionKey.cancel()只会在下一个select()操作有效,过了就会还原。同时注意:关掉连接记得关掉Socket之后再关SelectionKey,因为SelectionKey关闭之后Socket还是存在的。同时应该明白,ServerSocketChannel,SocketChannel关闭端口使用的是Socket的方法进行的。要关掉ServerSocketChannel就只需要关掉ServerSocketChannel所在的SelectionKey即可。(线程安全其实只说到大概,还需深入研究掌握,未完成)




(未完成)


        JMS(java信息服务)(未完成)

        RPC(远程过程调用)(未完成)

        RMI(调用远程对象方法)(未完成)

(注意,在java中知名的远程应用级协议有:RMI,XML-RPC,binary-RPC,JMS,SOAP等。未完成,需要掌握)





HttpGet,HttpPost,HttpRequest,HttpRespond,Channel,Selector,HttpClient,DefaultHttpClient,NIO,AIO,RMI,JMS,JDBC,EJB(未完成)


//未使用的资料

        (对于网络编程这个版块,主要内容有,网络模型,协议,数据传输,网络io,而实际上我们需要进行的只是相关类的掌握即可)

        网络不等于网页,因此暂时不涉及网页的编程。对于网络其实最关键的就是数据传输,这方面是最基础的又是最重要的,通常都是基于socket进行封装,或者直接使用socket进行网络传输,这是较为基础,简单的,但是这个版块涉及到命令传输,数据库访问,而这些都是使用特定的类进行编程即可。关键是这方面的网络都是最基础的,因为基本上就只是数据传输为核心而已。

        网络编程实际还涉及到像OSI这样的网络模型,但是实际编程时就基本上是不涉及的,因为封装好了,假如不封装的话将会很麻烦,因此这里对于网络模型不必太纠结,更重要的是将精力放在实际应用的编程上,也就是应用层的编程。(osi有七层,internet模型只有四层)

        网络编程还涉及到网络的模式,也就是说像c/s,或者b/s这样的模型。

        网络编程的核心部分是涉及协议的那部分,这才是最重点,最核心,也是最难的部分。协议,其实就是数据传输时候的数据格式,传输以及接受双方都拥有这种协议,一边解析需得到或者发出的数据的这是目的,或者得到数据。因此,每一种协议都有自己的格式,我们只是将我们所要发出的东西进行数据封装得到实际发送的数据包而已。

     



        HttpResponse=DefaultHttpClient.execuate(HttpRequest);以及HttpURLConnection=URL.openConnection();(默认是get模式,使用post模式需设置setRequestMethod())这两个是Http编程的关键式子。



(应该看一下netty这个java网络编程框架,以及NDK等。这里网络框架是非常重要的,需要多了解。)






(未完成)


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值