一、Android客户端

  • 创建可缓存线程池:Executors.newCachedThreadPool();该方法返回的是一个ExecutorService接口,而这个接口继承Executor接口,Executor只包含一个execute()。
  • execute()方法的参数为一个Runnable,返回值为void。
  • Message类:获取Message对象的最好方法是调用Message.obtain()或者Handler.obtainMessage(),  这样是从一个可回收对象池中获取Message对象。







  • 添加权限:

    unity IPointerDownHandler手机有用吗_列表

  • 在MainActivity中初始化界面元素,绑定按钮监听事件,注册广播来发送信息




    private void findView() {



        btnStartClient = (Button) findViewById(R.id.btn_tcpClientConn);



        btnCloseClient = (Button) findViewById(R.id.btn_tcpClientClose);



        btnClientSend = (Button) findViewById(R.id.btn_tcpClientSend);



        editClientPort = (EditText) findViewById(R.id.edit_tcpClientPort);



        editClientIp = (EditText) findViewById(R.id.edit_tcpClientIp);



        editClientSend = (EditText) findViewById(R.id.edit_tcpClientSend);



        MsgList = (TextView) findViewById(R.id.txt_MsgList);



    }






    private void bindListener() {



        btnStartClient.setOnClickListener(myBtnClicker);



        btnCloseClient.setOnClickListener(myBtnClicker);



        btnClientSend.setOnClickListener(myBtnClicker);



    }






    private void bindReceiver() {



        IntentFilter intentFilter = new IntentFilter("tcpClientReceiver");



        registerReceiver(myBroadcastReceiver, intentFilter);//注册广播



    }






    private void Init() {



        btnCloseClient.setEnabled(false);



        btnClientSend.setEnabled(false);






    }






  • 实现按钮“连接服务器”“关闭连接”“发送信息”的点击事件

      public void onClick(View view) {



            switch (view.getId()) {



                case R.id.btn_tcpClientConn:



                    btnStartClient.setEnabled(false);



                    btnCloseClient.setEnabled(true);



                    btnClientSend.setEnabled(true);



                    String ip=editClientIp.getText().toString();



                    String port=editClientPort.getText().toString();



                    tcpClient = new TcpClient(ip, getPort(port));



                    exec.execute(tcpClient);



                    break;



                case R.id.btn_tcpClientClose:



                    tcpClient.closeSelf();



                    btnStartClient.setEnabled(true);



                    btnCloseClient.setEnabled(false);



                    btnClientSend.setEnabled(false);



                    break;



                case R.id.btn_tcpClientSend:



                    SendMsg = editClientSend.getText().toString();



                    Message message = Message.obtain();



                    message.what = 2;



                    message.obj = SendMsg;



                    myHandler.sendMessage(message);//显示在消息列表中



                    exec.execute(new Runnable() {



                        @Override



                        public void run() {



                            tcpClient.send(SendMsg);//发送消息



                        }



                    });



                    editClientSend.setText("");



                    break;



            }



      }









  • 处理消息列表




    private class MyHandler extends android.os.Handler {



        private WeakReference mActivity;



        MyHandler(MainActivity activity) {



            mActivity = new WeakReference(activity);



        }



        @Override



        public void handleMessage(Message msg) {



            if (mActivity != null) {



                switch (msg.what) {



                    case 1://读取到的消息



                        MsgList.append("服务器:" + msg.obj.toString() + "\n");



                        break;



                    case 2://我发送的消息



                        MsgList.append("我:" + msg.obj.toString() + "\n");



                        break;



                }



            }



        }



    }






  • 新建TcpClient类,实现Runnable接口,创建客户端Socket对象,来接收、发送消息
  1. PrintWriter输出流,实现发送消息
  2. DataInputStream,实现接收消息




    public void send(String msg) {



        pw.println(msg);



        pw.flush();



    }



   @Override



    public void run() {



        try {



            socket = new Socket(serverIP, serverPort);



            socket.setSoTimeout(5000);



            pw = new PrintWriter(socket.getOutputStream(), true);



            mInputStreams = socket.getInputStream();



            mDataInputStream = new DataInputStream(mInputStreams);



        } catch (IOException e) {



            e.printStackTrace();



        }



        while (isRun) {



            try {



                rcvLen = mDataInputStream.read(buff);//接收消息



                rcvMsg = new String(buff, 0, rcvLen, "utf-8");



                Intent intent = new Intent();



                intent.setAction("tcpClientReceiver");



                intent.putExtra("tcpClientReceiver", rcvMsg);



                MainActivity.context.sendBroadcast(intent);//将消息发送给主界面



                if (rcvMsg.equals("QuitClient")) {



                    isRun = false;



                }



            } catch (IOException e) {



                e.printStackTrace();



            }



        }



        try {



            pw.close();



            mInputStreams.close();



            mDataInputStream.close();



            socket.close();



        } catch (IOException e) {



            e.printStackTrace();



        }



    }



    






  • 处理接收到的消息,显示在消息列表中

  



    private class MyBroadcastReceiver extends BroadcastReceiver {



        @Override



        public void onReceive(Context context, Intent intent) {



            String mAction = intent.getAction();



            switch (mAction) {



                case "tcpClientReceiver":



                    String msg = intent.getStringExtra("tcpClientReceiver");//msg:读取到的消息



                    Message message = Message.obtain();



                    message.what = 1;//用户自定义的消息代码,这样接受者可以了解这个消息的信息



                    message.obj = msg;//obj:发送给接收器的任意对象



                    myHandler.sendMessage(message);



                    break;



            }



        }



    }






二、Unity服务器端






  使用TcpListener实现Unity服务器端,具体流程参照http://blog.sina.com.cn/s/blog_1322690230102y3l4.html,接下来补充一些功能






  • 持续监听客户端请求

 



     void StartServer()



    {



        /// 1.建立TCP监听器TcpListener对象。



        listener = new TcpListener(IPAddress.Parse(NetworkValue.ip), NetworkValue.port);



        Debug.Log("服务器已开启: ip-" + NetworkValue.ip + "     port-" + NetworkValue.port);



        listener.Start();                                                             ///2.启动监听器






        //侦测连接的客户端



        while (true)



        {



            ///3.等待客户端连接过来



            TcpClient tcpclient = listener.AcceptTcpClient();//已连接的客户端,阻塞方法



            Debug.Log("一个新用户! Client : " + tcpclient.Client.RemoteEndPoint);






            if (_clients.Count < maxConnected)



            {



                //建立玩家连接类(开启每一个玩家的单独线程)



                client = new ClientSocket(tcpclient);



                _clients.Add(client);



            }



            else



            {



                //向该用户发送"已满"



                Thread.Sleep(500);  //暂停线程500ms



                tcpclient.Close();



            }



        }



    }






  • 手动控制信息的发送




    SendBtn.onClick.AddListener(delegate



            {



                sendMsg = inputText.text;



                inputText.text = "";



                textTest.text += "我:" + sendMsg + "\n";



                client.sendQueue.Enqueue(sendMsg);



            });






三、通讯效果:






    

unity IPointerDownHandler手机有用吗_列表_02

 

unity IPointerDownHandler手机有用吗_列表_03





四、Android与Unity工程源码: