这是客户端的通信代码:
Observable.create(new Observable.OnSubscribe<ParkingItem>()
{
@Override
public void call(Subscriber<? super ParkingItem> subscriber)
{
try
{
//连接服务器
socket =new Socket();
socket.setSoTimeout(5000);
socket.connect(new InetSocketAddress(IpAndPort.ip, IpAndPort.port), 5000);//连接服务器 如果超时则抛出异常 dataOutputStream =new DataOutputStream(socket.getOutputStream());
dataInputStream= new DataInputStream(socket.getInputStream());
dataOutputStream.writeInt(2);
dataOutputStream.writeInt(finalI);//告诉服务器从第几个开始获取
dataOutputStream.flush(); int a =dataInputStream.readInt();//表示可以读几个
for (int i = 0; i <a ; i++)
{
String title=dataInputStream.readUTF();
String text = dataInputStream.readUTF();
String imagepath=dataInputStream.readUTF();
int id=dataInputStream.readInt();
subscriber.onNext(new ParkingItem(title,text,imagepath,id)); }
CloseLoading();
subscriber.onCompleted();
} catch (IOException e)
{
e.printStackTrace();
subscriber.onError(e);
}
finally
{
try
{
dataOutputStream.close();
dataInputStream.close();
socket.close();
} catch (IOException e)
{
e.printStackTrace();
Log.d("drcw","final抛出异常"+e.toString());
}
}
}
}
这是服务器的通信代码:try
        {
            dataInputStream = new DataInputStream(socket.getInputStream());
            dataOutputStream = new DataOutputStream(socket.getOutputStream());            int firstInt = dataInputStream.readInt();
            
            switch (firstInt)
            {
       
                case 2:
                    int i =  dataInputStream.readInt();//读取从第几个开始获取
                    ArrayList<ParkingItem> list= postManages.getPostsList();
                    if (i+5-1<list.size())
                    {
                        dataOutputStream.writeInt(5);
                        for (int ii = i; ii <i+5 ; ii++)
                        {
                            dataOutputStream.writeUTF(list.get(ii).getTitle());
                            dataOutputStream.writeUTF(list.get(ii).getText());
                            dataOutputStream.writeUTF(list.get(ii).getImagepath());
                            dataOutputStream.writeInt(list.get(ii).getId());
                            try
                            {
                                Thread.sleep(13);//限速防崩
                            } catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }
                    else
                    {
                        dataOutputStream.writeInt(list.size()-i);
                        for (int ii = i; ii <list.size() ; ii++)
                        {
                            dataOutputStream.writeUTF(list.get(ii).getTitle());
                            dataOutputStream.writeUTF(list.get(ii).getText());
                            dataOutputStream.writeUTF(list.get(ii).getImagepath());
                            dataOutputStream.writeInt(list.get(ii).getId());
                            try
                            {
                                Thread.sleep(13);//限速防崩
                            } catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }
                    dataOutputStream.flush();                    break;
                
            }        } catch (IOException e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                dataInputStream.close();
                dataOutputStream.close();
                socket.close();
            } catch (IOException e)
            {
                e.printStackTrace();
            }
        }明明就是一个write对应一个read,为什么大部分时候就正常,偶尔就抛两个eof异常呢?

解决方案 »

  1.   

    自己看readInt()的源码翻译一下吧,我就不多说了
      

  2.   

    你客户端的dataOutputStream和dataInputStream我看是全局的,又看到有类似for循环的子线程赋值,应该是并发问题导致的,把这两个的声明放到子线程应该就不会有问题了
      

  3.   

    我的资源里有用socket传输文件的,没有遇到这种异常,你有兴趣可以去下载
      

  4.   

    引用全局变量肯定都会有并发问题啊,每个线程都对他进行赋值,然后再调用,如果线程1赋值后刚好线程2又立即赋值,这时线程1和线程2都会读同一个对象,不就相当于读取2遍当然会越界了。
    给你举个简单的例子吧
    public class JavaMainTest {
        static String aaa = null;    public static void main(String[] args) {
            new Thread() {//线程1
                @Override
                public void run() {
                    aaa = "数据1";
                    try {//sleep一下,模拟多线程后抢占到资源的效果
                        sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(aaa.length());//读取aa的length
                    aaa = null;//读取完释放,模拟流结束会close
                }
            }.start();
            new Thread() {//线程1
                @Override
                public void run() {
                    aaa = "数据2";
                    //此处不close模拟多线程先抢占到资源
                    System.out.println(aaa.length());//读取aa的length
                    aaa = null;//读取完释放,模拟流结束会close
                }
            }.start();
        }
    }想明白为什么会抛出空指针异常你就懂了
      

  5.   


    谢谢您的回复,这个多线程共用一个全局变量的问题我知道的,我说的单线程的意思是,Observable.create()这个函数只会执行一次,所以应该不会有两个线程同时读写全局变量的情况吧?Rxjava我刚刚学习,不太熟悉,可能有什么我搞错了。不过确实应该将这两个变量放在函数内,谢谢您的回复!
      

  6.   

    用了Socket一定是在子线程,毋庸置疑的,主线程会直接崩溃。你的rxjava下面应该有写到哪个线程里面