在Java的Socket编程中,我们经常会遇到第一个包对方可以收到,第二个包就连接重置,这其实是因为对方第二个包的数据过大被TCP分开了,然后对方接收到了第一个包,导致read阻塞结束,然后程序结束,Socket关闭很巧的是,up在开发CraftGame的时候也遇到了同样的问题,在网络上找了很多方法,其中很多都是用各种开源库,比如apache的库,而up是纯Socket编程,那我们该怎么办呢?答案就是:多线程,就输入输出各一个线程,然后用一个类似NetStatus的东西记录要读取的数据长度和读取到的数据还有要写出去的数据,然后写一个getData方法,如果数据不为null则返回数据,那么怎么实现呢?下面up就来分享一下up的具体实现
写一个输入线程和输出线程,我们暂时把他叫做InputThread和OutputThread,还有一个储存各种状态的类,我们暂时把他叫做NetStatus,然后里面声明一些变量,因为是多线程,所以为了避免数据不能及时更新,所以我们要用volatile修饰变量,然后InputThread要获取NetStatus里面的输入长度,然后读对应的长度,记住读的操作要在循环的末尾,不然会阻塞线程无法返回数据。然后每读一个字节在NetStatus的标记里面+1,直到标记大于或等于输入长度,就输出数据到NetStatus的数组里面(用完赋值为null),如果只要指定长度的数据呢?用ByteArrayInputStream实现就可以了
那么在输出到NetStatus的数组之前数据存在哪里呢?ByteArrayOutputStream,向里面写数据,别忘了reset方法,把数据和标记清空(不会把NetStatus的字节数组清空)OutputThread很简单,写NetStatus的输出数组就行了,就是要标记一下写没写,如果写过了就不写,然后用这种方法代替直接读写吧!希望这种方法能帮到你们