00:01
各位同学大家好,在前面的内容中呢,咱们已经完成了Java n IO里边相关的知识的讲解,那咱们最后一个内容呢,我们就通过前面学的知识来完成一个Java n IO的综合案例,咱们使用NIO里面的技术来实现一个多人聊天室的这么一个功能,那下面呢,咱就开始写下这个综合的案例。首先我先把这个项目环境我们搭建一下,我这里边提前创建了一个Java工程,就是一个普通的Java工程,我们起名叫A硅谷NIO,这个SH,这是我们做的这么一个创建。在聊天室的功能里边呢,肯定会涉及到客户端,包括服务端过程,所以说我在里边建了两包,一个叫server,一个叫client,那首先我们先建我们的服务端的过程,咱们先开始开发咱们服务端代码,那我在里边,现在我来创建一个服务端的这么一个类,那这个类我起名叫这个chat,这个so,我写一下啊,Chat so。
01:17
这是我们创建的这么一个服务端的这么一个类,咱们把它做了一个创建。这个类呢,创建之后我在上面加上一个注释,是咱们聊天室这个服务器的这么一个部分,然后写完之后在里边我们加上这么一个问方法,所以咱们这个服务器端的一个入口,所以现在这么一个基本的一个类我们都创建,然后创建之后我们在客户端里边咱们也是建个类,这个类我起名叫这个这个client。我写下。Client,然后在里边我们也是啊,写上一个注释,这作为我们的聊天室的客户端的这个部分,所以现在咱把两个类我们就完成创建,然后创建之后,首先我们先写这个聊天室的服器端,把这个代码我们先做实验。
02:14
那下面我来写一下这个代码,在这个代码中呢,首先我们先这里边咱写个方法,作为咱们这个服务器端启动的这么一个方法,把这个方法我们来创建一下,那我来写一下啊,我们起个名字,我叫,然后我起名,比如叫这个start server。就是启动咱们的服务器端,这是我们做的这么一个创建,然后创建之后在里边我们来完成它的用的代码。那这个代码怎么写呢?按照我之前习惯,我在里边呢,还是把代码的步骤给各位先列出来,然后咱们根据步骤一步一步把代码我们做个实现。
03:02
首先在里边的第一步操作,咱们肯定要创建这么一个select选择器。这个我写一下,这是我们的第一步操作,一会儿我们来实现,然后里边的第二步操作,咱就要创建这么一个叫server socket channel这么一个通道,咱们把它做创建,然后写下啊,就是server。Socket。China。这么一个通道,这是我们的第二步操作,然后这个做到之后,咱的第三步做什么呢?是不是要为这个通道绑定咱们监听那个端口,这是我们的第三步,我写一下啊,为我们这个China。通道。绑定咱们监听的那个端口,这是里边的第三步。然后这个做到之后呢,咱的第四步干什么呢?咱是不是要循环去看一下我的通道里边是否有我的事件已经就绪了,如果就绪的话,根据他的状态,咱是不是在调方法,做各自的业务处理,所以这是我们的第四步,我写一下啊,就是咱们循环。
04:16
然后咱们看一下通道,或者说等待我们这里边。是否有这个就是新的这个连接进行这么一个接入啊,就是这个过程,如果有的话,那咱们往下进行,咱就写第五步,根据咱们这个就绪的状态,比如说你是一个接收的状态,你是一个可读状态等等,然后咱们根据状态去调用我们对应的这些方法,实现咱们那个具体那个业务上的这个操作。这是我们要完成的第五步,然后在第五中呢,如果说咱说的更具体点,那我们写一下啊,在5.1步中,如果说它是一个这么一个,就是这个事件。
05:05
或者说save这个就绪的状态,那我们实现我们的操作,另外咱们再做处理,就是5.2,如果说它是一个可读的这么一个状态,那咱们在做其他的处理,所以这就是我们在里边写的一个最基本的一个过程,咱们就是按照这个过程实现咱们最终的这个操作,比如说如果是这个三状态,那么设成可读,可读里边得到客户端发送过来的消息,把消息再分发,或者说广播给其他的客户端,所以咱们一会儿继续来说明,所以现在我就把这个最基本的步骤给各位写出来了。步骤呢,写完之后,下面呢,我们就根据步骤,咱们把这个代码我们最终来实现一下,那我们来写一下啊,首先第一步咱们先创建一个select选择器,那我写一下。
06:03
我们用这个。里边的这个方法它叫open方法,咱们把这个select选择器,我们先做个创建,这是里边的第一步操作,有异常给他直接就择入的出去。这步做到之后呢,我们的第二步操作,咱们通过这个叫serve so来创建这么一个的这么一个通道,那我把这通道创建,我起名叫server soet channel,这是第二步操作,然后第三步咱们为通道里边绑定咱们监听那个端口,那我来绑定用这个叫。办的方法。里边扭上这么一个对象,比如说咱们的端口就是这个8000的这个端口。这是我们写到里边的第三步,然后这个写完之后咱到第四步,这里边就是循环做操作,但是操作之前呢,其实咱还有一个步骤,刚才没有写到啊,咱需要把我们的通道是不是要设成一个叫非阻塞的一个模式,这个我们来做个设置server。
07:09
So China。点上config block这个值我们改成false,这样的话设置成非组合模式,这是我们的第三步,然后做完之后咱的第四步,那就开始做,里面这个就是循环,等待是否有新的链接进行进入,当然过程中呢,我们在操作中咱们说的具体点啊,第四步中呢,咱在循环之前是不是要把你这个channel。也就这个通道。是不是要注册到你这个选择器上面来。是不是要这里边做这个过程,所以咱把这个做到,那我们来写一下啊。在里边用server点上,然后在里边加上咱们这个那种,第一个就是你的选择器,第二个是你感兴趣这个事件,比如说你是接收还是什么可读还是什么其他事件,那我们来一个selection key。
08:11
点上这么一个就是accept接收这个。感兴趣的这个事件,所以现在啊,咱们把这个过程就完成了,这是第四步,这个完成之后,比如说为了咱们后面测试更加方便,咱们向控制台做个输出,我写一下,比如写一下就说这个服务器它已经就是。正常启动了,或者已经启动成功了。咱们就写上这么一个输出,为了咱们看的更明显,然后这个做完之后,咱的第五步,就刚才提到的,我们要做这么一个,就是循环,包括做题过程。那我们来写一下,呃,那我这么来做啊,我把这个咱换成第四步,其实这算是我们这里边的,咱给它单独列出来,第四步是注册,然后第五步咱就做这个循环的这个操作。
09:04
第六步,咱根据状态再做实现。所以咱们把这步骤再进一步完善一下啊。那下面呢,我们写这个循环,循环呢,你可以写一个while,然后里面加个处,这么写是可以的,或者说呢,你可以写另外一种写法,给各位再换一种写法啊,咱可以来一个后循环。注意啊,我在for循环里边的加上就是两个这个分号,这样的话呢,也能做一个循环,跟我们写那个while处是一样的,它会一直循环下去,两个代码的效果是一样的,只是底层这个更优啊,就是它的底层编译之后。代码更少,所以咱们用这种方式实现,但是你写Y处也是一样的,然后这个选完之后,咱往下来看啊,下面做什么呢?咱就获取一下你那个通道,就是通道那个数量啊,给他获取一下,就是获取一下。
10:00
我们这个这个数量。然后怎么获取呢?咱们通过这个selector里边这个方法就叫select方法,把这个通道给它获取到,这单之前应该也做过啊,然后给它起个名字,我就叫这个。Channels。这是我们获取里面这个数量。然后获取之后呢,我们之前提到这个值是一表示获取到,就是你感性事情那个就绪了,那比如这个值等于零,那就表示没有,那咱们给他做一个完整的判断啊,我写一下啊,就是。如果说里边这个read channels值等于零,那就表示咱们没有获取到,没有获取到的话呢,那我加上一个continue,让它跳出当前循环。啊,这个做到之后,下面我们继续来获取,咱们就获取一下就是可用的,这个就是China。
11:03
把它放到咱们那个集合里面去。咱们来获取一下啊,那我来写一下,我们用里面这个方法叫做selected。然后它返回到大家注意是不是一个set集合,得到这个集合,那在下面的把这集合我们做一个便利。就是便利这个集合,那我们来快速写一下啊。咱们通过一个迭代器的方式做个便利,我们加上这个。然后在里边我们继续往下写,我们加上这么一个写一下啊,就这里。加上这么一个叫while while里边的加上点哈西nice的,咱给它往下里边这个,然后这个便利之后,咱们取到里边的某一个,或者说每一个channelator,点上nice方法。
12:00
把里边的每个这个取到,那我们起个名字就叫selection key,这样的话就取到了里面的内容,然后取到之后大家注意啊。因为现在咱是从集合中是不是要取出来那些通道,然后再做判断,看它是什么状态,所以你取出来之后是不是就不能再取第二次,因为你已经取出来了,所以咱们取出来之后,那我昨天事情啊,做什么事情呢?就是移除掉你那个set集合里边当前的这个selection key,把这给它需要移除掉,因为咱们已经给它取出来了。Now用。点上这个方法把它移除掉,这个我要注意啊,因为你已经取出来了,然后这个做到之后,下面写的就是咱们刚才说的第六步操作,我把这个步骤给各位拿回来,咱们做法就是根据就绪状态调用对应的方法做个处理,那下面咱就做个判断,我在里边写一下啊。
13:03
首先我们先加上1IF,也就是说如果说里边这个selection key它的状态,咱们加个方法,大家看这方法是不是这个accept这个状态,如果他是这个状态,那这个状态那咱就做其他的处理。啊,这里边我先加个注释啊,比如咱来一个这个do something。一会儿咱快速做实现,这是我们的第一个判断,然后咱们再判的一个状态,我再加上这么一个if。在里边写下。就是如果说key它的状态是一个read able就是一个可读状态,那我们再做一些其处理,所以大家注意啊,就是现在我就按照刚才咱们写的步骤,把这个代码的基本结构咱是不是就写出来了,这是咱们刚才写到这个过程。然后这个过程呢,给各位再重复一遍啊,咱们再进一步完善,首先做法就是第一步创建C选择器。
14:05
第二步创建server so channel通道,第三部分绑定端口号,设置成它这个非组模式,然后进行注册,注册之后咱就循环等待有新的链接接入,如果等于零没有,然后这里边啊,我们依次循环等待有进行接入,如果有的话,那咱把通道取到便利,根据状态做判断,如果你是S状态,我们调方法做处理,如果你是可读状态,我们再调其他方法再做就的处理。所以现在咱就把这个服务端的基本的结构就写出来了,然后一会儿我们再进一步完善这两个状态分别咱们要做什么事情。
我来说两句