从网上看了一些demo,然后写到自己的项目当中,运行发现有些地方还是不对,当然,肯定是我理解的有问题,我不愿意把锅留给自己,于是研究完了之后写一个最简单的demo,希望大家都能懂。
不多说,进入正题。
一。保证两个手机在同一个wifi网络当中,这是很重要的。
二。一个手机作为android客户端,另一个作为server端
首先来看android端代码:
private int i = 1; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_send_msg = (Button) findViewById(R.id.btn_send_msg); btn_send_msg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { i = i + 1; Log.e("tcp_android", "点击事件执行"); new Thread(new Runnable() { @Override public void run() { try { Log.e("tcp_android","Client:Connecting"); //IP地址和端口号(对应服务端),我这的IP是另一个手机的ip地址,后面会介绍怎么看 Socket socket = new Socket("192.168.1.236", 12345); Log.e("tcp_android","socket连接完成"); //发送给服务端的消息 String message = "Message from Android phone " + i; try { Log.e("tcp_android","Client Sending: '" + message + "'"); //第二个参数为True则为自动flush PrintWriter out = new PrintWriter( new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())), true); out.println(message); // out.flush(); } catch (Exception e) { e.printStackTrace(); } finally { //关闭Socket socket.close(); Log.e("tcp_android","Client:Socket closed"); } } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } }); }
其实客户端要注意的东西就两个,就是new socket(参数1,参数2)。好多人卡在了这个参数应该怎么写,那么我用两个手机来举例子,客户端这儿第一个参数应该是作为服务端的手机的ip地址,你可以进手机的设置当中查看,至于具体的操作,百度是可以查到的,在这里就不多做介绍了,另一个端口号,你就随便填写吧,12345,12346,12347,只要和服务端的端口号保持一致就行。还有记得,这个通信是耗时操作,要在子线程中执行喔;
下面来看看服务端的代码:
private static final int SERVER_PORT = 12345; private TextView mText_accept_msg; private String mStr = ""; private String TAG = "tcp_android"; private MyHandler mMyHandler;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMyHandler = new MyHandler(); mText_accept_msg = (TextView) findViewById(R.id.text_accept_msg); new Thread(new Runnable() { @Override public void run() { try { Log.e("tcp_android","Server: Connecting..."); ServerSocket serverSocket = new ServerSocket(SERVER_PORT); while (true) { //循环监听客户端请求 Socket clientSocket = serverSocket.accept(); Log.e("tcp_android","Server: Receiving..."); try { //获取输入流 BufferedReader in = new BufferedReader( new InputStreamReader(clientSocket.getInputStream())); //获取从客户端发来的信息 mStr = in.readLine(); Log.e("tcp_server","Server: Received: '" + mStr + "'"); Bundle bundle = new Bundle(); bundle.putString("msg", mStr); Message message = new Message(); message.setData(bundle); mMyHandler.sendMessage(message); Log.e(TAG, "handler发送消息" + mStr); } catch (Exception e) { Log.e("tcp_android","Server: Error"); e.printStackTrace(); } finally { clientSocket.close(); Log.e("tcp_android","Server: Close."); } } } catch (Exception e) { Log.e("tcp_android","Server: Error"); e.printStackTrace(); } } }).start(); } class MyHandler extends Handler{ public MyHandler() { super(); } @Override public void handleMessage(Message msg) { super.handleMessage(msg); Bundle data = msg.getData(); String string = data.getString("msg"); Log.e(TAG, "handler接收消息:" + string); mText_accept_msg.setText("接收客户端消息:" + string); } }
服务端接收也是得在子线程不断的循环接收,这个只是最简单的demo,讲明原理,至于那些封装思想什么的,就靠自己来弄了,以后肯定是要有线程池管理的,不管是客户端还是服务端,为了看得清楚,我在服务端的xml文件中写了一个textview,不断的设置文字,因为要修改UI,必须在主线程执行,而接收的消息又是在子线程,所以这时候,借助handler来实现,这块就不再多说了,相信都懂,好了,这样就实现了基本的通信,过后,我会把服务器给客户端下发消息的补上。。。