解决方案 »

  1.   

    我试着修改了一下,发现如果把接收线程写在主Activity里面,程序就是正常工作的,这说明服务器那边没有问题:
    public class MainActivity extends Activity 
    {
    EditText ip_box;
    Button login_button;
    TextView text;
    Handler handler;
    final int port = 12121;
    ClientSocketManager client_socket_manager;
    Socket socket;
    String ip;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    init();

    handler = new Handler()
    {
    public void handleMessage(Message msg)
    {
    String words = (String)msg.obj;
    if( words.equals("ok") == true )
    {
    Toast.makeText(MainActivity.this, "来自服务器的问候:登陆成功!!欢迎使用~",Toast.LENGTH_LONG).show();
    finish();
    }
    else if(words.equals("did not login") )
    {
    Toast.makeText(MainActivity.this,"ip错了或者是主机没有开", Toast.LENGTH_SHORT).show();
    }
    else
    {
    text.setText((String)msg.obj);
    }
    }
    };

    class GetThread implements Runnable //接收线程
    {
    public void getMsg()
    {
    try 
    {
    Scanner in = new Scanner(socket.getInputStream());
    String gotmsg = in.nextLine();
    Message msg = new Message();
    msg.obj = gotmsg;
    MainActivity.this.handler.sendMessage(msg);

    } catch (UnknownHostException e) 
    {
    Message msg = new Message();
    msg.obj = "net error";
    MainActivity.this.handler.sendMessage(msg);
    } catch (IOException e) 
    {
    Message msg = new Message();
    msg.obj = "net error";
    MainActivity.this.handler.sendMessage(msg);
    }

    }

    @Override
    public void run() 
    {
    try 
    {
    socket = new Socket();
    socket.connect(new InetSocketAddress(ip, port) , 5000);
    } catch (UnknownHostException e) 
    {
    Message msg = new Message();
    msg.obj = "did not login";
    MainActivity.this.handler.sendMessage(msg);
    } catch (IOException e) {
    Message msg = new Message();
    msg.obj = "did not login";
    MainActivity.this.handler.sendMessage(msg);
    }

    if( socket != null)
    getMsg();
    else
    {
    Message msg = new Message();
    msg.obj = "did not login";
    MainActivity.this.handler.sendMessage(msg);
    }
    }
    }

    login_button.setOnClickListener(new OnClickListener()
    {
    @Override
    public void onClick(View arg0) 
    {
    // TODO Auto-generated method stub
    ip = ip_box.getText().toString();
    client_socket_manager = new ClientSocketManager(ip, port, handler);
    boolean logged = client_socket_manager.login();
    GetThread g = new GetThread();
    new Thread(g).start();
    }

    });
    }}
    但是,我试图把网络操作分离出去的时候,就会出现IOException,分离之后的代码如下:
    public class ClientSocketManager //管理网络的类
    {
    String ip;
    int port;
    Socket socket;
    Handler handler; //通过这个handler发消息

    /**
     * Thread to get message from server
     * @author Zero
     *
     */
    class GetThread implements Runnable
    {
    @Override
    public void run() 
    {
    try 
    {
    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
    while(true)
    {
    String input = in.readLine();
    if(input!=null)
    {
    Message msg = new Message();
    msg.obj = input;
    handler.sendMessage(msg);
    }

    }
    catch (IOException e) 
    {
    System.out.println("NetThreadIOException");
    Message msg = new Message();
    msg.obj = "net error";
    handler.sendMessage(msg);
    }
    catch (NullPointerException e)
    {
    //System.out.println("NetThreadIOException");
    Message msg = new Message();
    msg.obj = "net error";
    handler.sendMessage(msg);
    }
    }
    }

    /**
     * Thread to login to server
     * @author Zero
     *
     */
    class LoginThread implements Runnable
    {
    boolean ok;
    @Override
    public void run() 
    {
    try 
    {
    socket = new Socket();
    socket.connect(new InetSocketAddress(ip, port) , 5000);
    } catch (UnknownHostException e) 
    {
    System.out.println("UnknownHostException");
    Message msg = new Message();
    msg.obj = "did not login";
    handler.sendMessage(msg);
    ok=false;
    } catch (IOException e) {
    System.out.println("IOException");
    Message msg = new Message();
    msg.obj = "did not login";
    handler.sendMessage(msg);
    ok=false;
    }
    }
    }

    public ClientSocketManager(){}

    /**
     * Create a new ClientSocketManager
     * @param _ip
     * @param _port
     * @param _handler
     */
    public ClientSocketManager(String _ip, int _port, Handler _handler)
    {
    ip = _ip;
    port = _port;
    handler = _handler;
    }

    public boolean login()
    {
    LoginThread login_thread = new LoginThread();
    new Thread(login_thread).start(); return login_thread.ok;

    }

    public void openGetThread()
    {
    GetThread getThread = new GetThread();
    new Thread(getThread).start();
    }
    }然后主Activity中:
    login_button.setOnClickListener(new OnClickListener()
    {
    @Override
    public void onClick(View arg0) 
    {
    // TODO Auto-generated method stub
    ip = ip_box.getText().toString();
    client_socket_manager = new ClientSocketManager(ip, port, handler);
    boolean logged = client_socket_manager.login();
    //if(!logged)
    // return;
    client_socket_manager.openGetThread();
    }

    });这样就会在input = in.readLine()那一行爆出IOException。请问这是怎么回事?谢谢~~
      

  2.   

    client_socket_manager.login();这句开的线程在login,马上就执行下一句 client_socket_manager.openGetThread();
    如果login的线程挂起或未login成功,那socket肯定是null,后面读信息,怎么读呢?
    应该是确保login成功后,再oopenGetThread()。
      

  3.   


    谢谢,检查了一下,确实是这个的问题,我现在用join()等待LoginThread结束以后再执行openGetThread就没问题了~