00:01
我们接着完成第二部分服务器接收客户的客户端的消息,并且呢,要实现转发,同学们转发的时候呢,有一个情况大家需要考虑,就是要排除自己,比如说。我这个客户端大家可以看到。这个客户端呢,它是50037,对他在发送消息的时候呢,就不用在回送给自己了,所以说在转发的时候呢,要排除自己,好现在呢,我们来进行一个编写,我们这儿不是要专门处理。就是读读数据的,就是读客户端的数据的。呃消呃,这个逻辑吗?那么现在我们来写一个方法,专门写一个方法来写到这里哈。编写,我们这样写就是。读取,读取客户端消息。
01:00
读取客户端的消息呢,非常简单,我们写一个private,然后VO直接写个read。那同学们知道我在读消息的时候,其实是要从哪里读啊,是要从。它相关联的通道来读取,因此呢,你在这至少要给我传一个selection k过来,这个没问题吧,因为我会通过你传过来的select k反向获取到对应的channel,然后再读取。好的,那现在呢,首先我们来做这样一个处理哈,我们先定一个。定义。定义一个什么呀,Shocked。So China。那现在开始写,呃,这样写哈,Shocked channel,我们就取个名字叫channel吧。初始化,我们这为一个空,然后呢,TRY开始了。
02:02
Catch,如果有异常,我们进行一个补货。好的。在这个踹块里面我们写什么东西呢?对,首先取得。取得。渠道,渠道关联的,关联的这个channel。是不是,所以也可以直接把这句话写到里面一样的。这句话我们就不要了,干脆我们就直接写到这里面。对吧。直接写到这里面也可以。写到这里面,呃还不行,因为我们还得写到外面,因为在catch里面呢,我们有可能要对出现异常的时候,呃进行一个处理,还是定到外边比较好。好,得到。得到什么呢,China?得到的方法当然很简单,直接等于我们这一个k.channel然后把它强转一下。
03:03
转成什么类型呢?转成我们socket channel前面是不是也用过呀,拿到了拿到China以后,下面我们干什么呢?我们是不是要创建缓冲buffer。因为我们在读的时候,其实是要从这个China里面把里面数据读到buffer里面去,所以说我要创建一个buffer buffer起呢,我们还是用bad buffer,前面已经讲了,Bad buffer就字节buffer点。Locate。写个1024。产生一个buffer。得到这个buffer以后,下一步呢,我们就可以来读取了,读取就是channel点什么呀,Read。Read读到我们这个buffer里面去。同样它会整个读取的时候呢,会返回一个值,就是我们读取到的长度,所以说这边呢,我们这写一个count。
04:02
读取到程度。好,这边呢,他说有一个异常没有处理好,我们把它处理一下,议一下,好,这边如果有异常呢,我们先暂时先输出一下,后面还会有其他的逻辑。大家可以看到。这个地方我们读取到,从这个China里面读取数据到buffer过后呢,它会返回一个count,那现在呢,我们看看到底有没有读取到,因为你有可能读取到,有可能没有读取到,会有不同的逻辑处理,根据什么呢?根据count的值。做处理。做处理。好的,如果我们这个count注意跟上思路,它大于零说明什么呀。我们确实读取到数据了。这时呢,我们就干什么呢,把缓冲区缓冲区。的数据干什么呀?转成字符串并输出了我们读取到这个buffer里面,其实它是字节。
05:00
现在呢,我们要把转字符串非常简单,六一个string。因为只有字符串我们才能够输出来。String。好的,那我们把哪个放进去啊,就把刚才这个buffer。里面的得到这些数组放进去,然后得到消息mes,好拿到了,拿到这个消息过后呢,我们就可以输出了,我们可以输出该消息。该消息。好吧,具体怎么输出,那非常的简单,你要是简单一点,就这样直接输出就可以了。是不是就我们去?客户端from吧,就。是客户端消息是什么呢?加上就行,对不对就输出。然后下面还有没有处理完哈,下面还要做什么事情呢,同学们看。你你在这个地方,在是在服务器端输出了从客户端发送的消息。
06:02
对吧,但是呢,但是这里面呢,这里面是不是还要像什么呢,像其他。其他的这一个客户端转发消息。转发消息。也就是说我们打开这个图。说什么呢?说你这个客户端发了一个消息给服务器端,服务器端收到了,说你是,呃,比如说你说了一句话,我是谁谁谁,我拿到这个消息过后呢,服务器我显示了一下,是不是还得把这个消息转发给。其他的。客户端呀,所以说我们现在呢,还得做一个处理,就是干什么呀,向其他客户端转发消息,那这里呢,我们也专门写一个函数。我们专门写一个方法来处理。没问题吧?好的,那现在呢,我们再写下一个方法哈,再写下一个方法,我就。开始写。
07:00
转发消息。转发消息给什么呢?其他的客户。没问题,那其实这个客户呢,就是通道,说白了就是给通道发。因为你每个客户呢,对应的有一个通道是不是,所以说我就开始写,我们写一个方法叫什么呢?比如说叫private private void善。就是发消息,发信息,To什么呢?Other。同学们,大家想一想,你在发这个消息的时候,你应该把什么告诉我,我就可以发了呀?把什么告诉我,第一个就是嗯,这个消息本身。因为你要发消息,你要把发送的消息给我,因为你在这已经拿到消息了,第二个还有一个什么东西啊,因为你在发消息的时候,你要排除自己,注意看是给其他客户端发消息,要排除自己。
08:03
要去掉。去掉自己。就自如果是自己就是说比如说打个比方,我们这个客户端。这是A客户端,A客户端发了一个消息给我们服务器,服务器这边呢,他只需要把消息转发给B和C就可以了,所以说这边还有一个任务,你在转发的时候呢,要排除自己,所以说我们需要把当前的这一个channel。Socket channel传到这边来进行一个排除对不对,所以说我写个socket channel这边写个叫做。排除的exce PT就是呃,Self自己。好,自己呢,这个是我要排除掉的,好,下面就写。那下面怎么做呢,肯定就要变利了,对不对,我这先提示一句话。我要提示一句话,说服务器转发消息了,服务服务器转发消息。
09:00
转发消息中。便利什么呢?OK,大家还记不记得老师在前面讲过,我们可以通过select。Case把所有注册到他的通道都获取到,所以说我们要便利什么呢,所有的。所有注册到对注注册注册到select。上的。这个socket。并排除自己。并排除。排除慢呢,排除she。那非常简单,那就一句话的事就可以了,For循环,For循环,然后呢,我们这边是这样写的,Selection。K啊,就是K从哪里取呢?从select点取。同学们,是不是这个时候我们实际上就是把这个K里面的每一个SK取出来了。
10:03
取出来过呢,我们要这样去做哈,取出。取出通道。取出这个通过什么呀,通过这个K。哎,最近通过K。取出。取出对应的慢就是我们的China。好的,那这个非常简单嘛,K channel。对不对,然后VR。然后呢,我们这边就拿到了一个。这样的目标K。拿出来拿到这边我们换一个名称啊,这边这边应该是什么呢?是说呃,就叫China就行了,用用这个名称也行啊,因为他们实际上都继承了这个接口,是不是这次呢,我们就用圈的这个接口来接收,就不需要强转了啊,不需要强转直接就可以用这个呢,就是我们要发送的目标,比如说叫target channel。
11:03
或者要转发的啊,这次呢,我就没有像上次那样取出来过后还强转了一下,转成这个类型,我就直接用接口的形式来接收它返回的channel没问题啊,没问题,那下面拿到以后是不是我们要排除自己啊。排除自己。排除自己,怎么排除自己呢?因为你在这已经把自己传过来了,所以说一一个非常简单的道理啊,这样写就行了,他的channel对instance of。它呢,首先是要是这种实,它实际的类型。必须是socket channel,并且还要满足什么呀?Target channel它干什么呢?不等于self。不等于自己。完事,那这样子呢。既他既保证我们要发送的这个channel是一个socket channel,同时呢,它不是自己,这时我们就可以转发了。
12:05
转发的时候也非常简单哈,呃,这时我们怎么做呢?这个时候我们就可以转,就可以来。这样的操作了。哎,我们看怎么去操作比较好哈。转一下吧,还得把它转一下,因为大家看target呢,这里面。这个地方有right啊,有right,那么就这样试一下,我们这样子先转一下。转型。为了安全我们转下型,转型的话呢,我们就这样写target,把它转成socket。把它转成一个socket channel。没问题吧?把它转成一个channel。好,这边呢,我们叫做。目标就是往哪发的。目的地拿到这个以后,我们再干什么呀,我们再将这个SG。
13:01
干什么呢,存储到。存储到八分。存造一个buffer,对存做buffer的话呢,我们用前面学过的这个方法就可以了,Bit buffer点。是不是学过这个东西啊,然后呢,我们把m.get message。这些都这些方法我们在前面都用过。这个时候就有一个buffer了。对,Buffer,拿到一个buffer以后干什么呢?OK。将通道。将通道的数据,A会将buffer的数据,将buffer数据写入到通道中。将八份的数据。的数据写入通道。好的。形容通道是不是就应该调我们当前这个DST点什么方法呢?它的write方法。Right方法,好,Right方法里边我们直接把这个buffer扔进去。
14:01
就可以了。是不是这样子的,同学们好。宝贝,看这里面有一个什么问题啊?呃,我们看他这地方应该有一个异常没有处理,那异常的话呢,我们就这扔出去就可以了,说应该是个IO异常。扔出去这边就没错了啊,没错了,好,这就是我们转发消息的。就是把一个消息转发给其他客户端的一段代码。而这里面还有一个问题是哪里没处理呢?就是我们还需要去处理一下。这个。我们还需要处理一下什么东西呢?我们还需要处理一下,如果在读的时候出现了异常,比如说我们这个通道。在读的时候读不到数据了,可能是因为你这边关闭了。是不是,所以说我们在这里呢,就可以通过。有没有捕获到异常来提示什么呢?这个客户是否已经下线了,可以这么来玩一把,那现在呢,我们来在这加点东西啊OK,那在这里我怎么处理呢。
15:05
这边其实就是一个IO异常啊,其实可以把这个。异常范围缩小一点。那怎么做呢?我这样做,我这样做。好,我就如果发生了异常,我们就提示一句话,提示什么呢?提示这样一句话,Channel。就是现在这个channel,我们可以通过channel呢,拿到它的一个远程地址,就是这这个当前这个channel,如果我在读的时候发生异常,说明他离线了。离线的话,我就直接把这个地址打出来,我说一句话加。加什么呢?加某某某离线了。离线。理性。好,这个地方大家可以看到,因为你在get remote address的时候,还会有可能发生一个异常,所以说我们还把它再踹一下。诶,再踹一下就可以了,不然哈,包起来。
16:03
好的,Catch。这帮人又会发生一个IO异常捕获。输出异常信息。啊,就这样子的。那这个时候我们看到这个名称它已经啊定义了,那么这咱们换一个名称吧,叫一二。零好,这就离线,离线过后你要做相应的处理呢?做什么处理呢?大家觉得做什么处理?第一个是不是我们要取取消注册。取消注册了,我们不注册了,就把这个K呢cancel。OK,第二句我们要关闭。关闭这个通道。关闭这个通道,OK,关闭通道显然用的方法呢,就应该是China点。关闭通道就完事,就说如果说我们在这地方有这个问题的话呢,我们就把这个信息诶给他处理一下完事啊就是补货,补货的时候呢,提示某某某离线了,然后取消注册,关闭通道。
17:07
这就是这一段read data的代码的处理。那现在呢,我们只需要做一个动作,做什么动作呢?把它连起来,第一个在这里。他在读读,呃,读的时候我们是不是写了个read data,把什么放进去呢?把当前这个K传进去。在这里。是不是在读的过程中读完了并显示了客户信息过后呢,我们还要去转发。这里面我们就要写一个善。Info to other把什么传进去呢?大家看是不是传两个信息,一个是消息本身。第二个就是你当前这个通道,当前通道就全了。放进去就可以了,好,服务器端的代码我们就写完了。服务器端的代码就写完了,待会儿呢,我们还要测试好这一部分,哪一部分呢?就是关于服务器端接受客户端消息并实现转发。
18:03
并提示上线哦,上线好像还没写,把上线的提示也写一下,在哪里去哦,这上线也写了啊,上线也写过了,上线写了,离线也写了,数据转发,数据信息打印也写了,转发也写了,OK那。现在的服务器的第一部分和第二部分我们就写完了,其实就是把原先我们写的内容怎么样综合了一下而已。那么客服务器端,那客户端呢?我们在下一个视频为大家编写。
我来说两句