Andoid 4.4.2 多线程tcp 通信

andoid 4 以上的编程一个和之前版本最大的不同就是不能在主线程中做网络链接,即是不能在主activity中建立socket链接。socket链接要在新建的线程中建立,信息的传递如果需在控件中显示,通过Handler类来改变控件UI。

贴出服务端的代码

public class MyServer {
    
    public static ArrayList<Socket> socketList=new ArrayList<Socket>();

    public static void main(String[] args) throws IOException{
        // TODO Auto-generated method stub
        InetAddress addr = InetAddress.getLocalHost();
        String ip=addr.getHostAddress().toString();//获得本机IP
        String address=addr.getHostName().toString();//获得本机名称
        //查看服务器ip信息
        ServerSocket ss=new ServerSocket(30000);
        System.out.println(ip+"   "+address+"     "+ss.getLocalPort());
        
        //进行监听
        while(true){
            Socket s=ss.accept();
            //该信息输出说明服务器监听到有客户端传输到服务器的信息
            System.out.println("there is massage send to server");
            socketList.add(s);
            new Thread(new ServerThread(s)).start();
        }
    }
}
服务端线程

public class ServerThread implements Runnable {

    Socket s=null;
    BufferedReader br=null;
    InputStreamReader inp=null;
    public ServerThread(Socket s) throws IOException{
        this.s=s;
        br=new BufferedReader(new InputStreamReader(s.getInputStream(),"utf-8"));
        inp=new InputStreamReader(s.getInputStream(),"utf-8");
    }
    @Override
    public void run() {
        // TODO Auto-generated method stub
        //测试进入servverThread
        System.out.println("ServerThread  start");
        
        
        try{
            String content=null;
            System.out.println("ServerThread  start  in the try block");
            
            while((content=readFromClient())!=null){
                //查看客户端传输到服务器的信息
                System.out.println(content);
                for(Socket s:MyServer.socketList){
                    OutputStream os=s.getOutputStream();
                    os.write((content+"\n").getBytes("utf-8"));
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    private String readFromClient(){
        try{
            return br.readLine();
        }catch(IOException e){
            MyServer.socketList.remove(s);
        }
        return null;
    }
}

服务端的代码的主要功能是接受来自客户端的信息,再将接受到的信息,发送给所有链接上服务器的客户端。

下面是客户端的代码

public class MainActivity extends ActionBarActivity {
    EditText input,show;
    Button send;
    Handler handler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment())
                    .commit();
        }
        send=(Button) findViewById(R.id.send);
        show=(EditText) findViewById(R.id.show);
        input=(EditText)findViewById(R.id.input);
        handler=new Handler(){
            public void handleMessage(Message msg){
                if(msg.what==0x1233){
                    show.append("\n"+msg.obj.toString());
                }
            }
        };
        try{
            new Thread(new ClientThread(handler,send,input)).start();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class PlaceholderFragment extends Fragment {

        public PlaceholderFragment() {
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_main, container, false);
            return rootView;
        }
    }

}

客户端主线程主要是获取界面的按钮有两个EditText

子线程代码

public class ClientThread implements Runnable{
	private Socket s;
	private Handler handler=null;
	BufferedReader br=null;
	OutputStream out;
	Button send;
	EditText input;
	public ClientThread(Handler handler,Button send,EditText input) throws IOException{
		this.handler=handler;
		this.send=send;
		this.input=input;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		
		
		//在子线程中建立网络连接
		try{
			s=new Socket("192.168.1.101",30000);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		send.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				
				//获取输出流,输出input输入框中的信息
				try {
					out=s.getOutputStream();
					out.write((input.getText().toString()+"\n").getBytes("utf-8"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
			}
			
		});
		try {
			br=new BufferedReader(new InputStreamReader(s.getInputStream()));
			String content=null;
			while((content=br.readLine())!=null){
				Message mes=new Message();
				mes.what=0x1233;
				mes.obj=content;
				
				//在子线程中通过handler改变主线程中的ui
				handler.sendMessage(mes);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
在子线程中建立socket链接,发送信息,接受来自服务器的信息,通过handler将信息显示在界面上。


在AndroidManifest.xml  中加上链接网络的权限

    <uses-permission android:name="android.permission.INTERNET" ></uses-permission>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值