美文网首页
使用Socket

使用Socket

作者: 熊出没之大熊快跑 | 来源:发表于2019-01-28 14:50 被阅读0次

    Socket也称为“套接字”,是网络通信中的概念,它分为流式套接字和用户数据报套接字两种,分别对应于网络的传输控制层的TCP和UDP协议。TCP协议是面向连接的协议,提供稳定的双向通信功能,TCP连接的建立需要经过“三次握手”才能生成,为了提供稳定的数据传输功能,其本身提供了超时重传机制,因此具有很高的稳定性;而UDP是无连接的,提供不稳定的单向通信功能,当然UDP也可以实现双向通信功能。在性能上,UDP具有更好的效率,其缺点是不保证数据一定能够正确传输,尤其是在网络拥塞的情况下。

    使用Socket来通信,有两点需要注意,首先需要声明权限:

    图一

    其次要注意不能在主线程中访问网络,因为这会导致我们的程序无法在Android4.0及其以上的设备中运行,会抛出如下异常:android.os.NetworkOnMainThreadException。而且进行网络操作很可能是耗时的,如果放在主线程中会影响程序的响应效率,从这方面来说,也不应该在主线程中访问网络。实际上通过Socket不仅仅能实现进程间通信,还可以实现设备间的通信,当然前提是这些设备之间的IP地址互相可见。

    /*** 客户端*/

    public class TCPClientActivityextends Activityimplements View.OnClickListener {

    private static final int MESSAGE_RECEIVE_NEW_MSG =1;

        private static final int MESSAGE_SOCKET_CONNECTED =2;

        private ButtonmSendButton;

        private TextViewmMessageTextView;

        private EditTextmMessageEditText;

        private PrintWritermPrintWriter;

        private SocketmClientSocket;

        private HandlermHandler =new Handler() {

    @Override

            public void handleMessage(Message msg) {

    // super.handleMessage(msg);

                switch (msg.what) {

    case MESSAGE_RECEIVE_NEW_MSG: {

    mMessageTextView.setText(mMessageTextView.getText() + (String) msg.obj);

    break;

                    }

    case MESSAGE_SOCKET_CONNECTED: {

    mSendButton.setEnabled(true);

    break;

                    }

    default:

    break;

                }

    }

    };

        @Override

        protected void onCreate(@Nullable Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

            setContentView(R.layout.activtiy_tcpclient);

            mMessageTextView = findViewById(R.id.msg_container);

            mSendButton = findViewById(R.id.send);

            mSendButton.setOnClickListener(this);

            mMessageEditText = findViewById(R.id.msg);

            Intent service =new Intent(this, TCPServerService.class);

            startService(service);

            new Thread() {

    @Override

                public void run() {

    connectTCPServer();

                }

    }.start();

        }

    @Override

        protected void onDestroy() {

    super.onDestroy();

            if (mClientSocket !=null) {

    try {

    mClientSocket.shutdownInput();

                    mClientSocket.close();

                }catch (IOException e) {

    e.printStackTrace();

                }

    }

    }

    @Override

        public void onClick(View v) {

    if (v ==mSendButton) {

    final String msg =mMessageEditText.getText().toString();

                if (!TextUtils.isEmpty(msg) &&mPrintWriter !=null) {

    new Thread(new Runnable() {

    @Override

                        public void run() {

    mPrintWriter.println(msg);

                        }

    }).start();

                    mMessageEditText.setText("");

                    String time = formatDateTime(System.currentTimeMillis());

                    final String showedMsg ="self" + time +":" + msg +"\n";

                    mMessageTextView.setText(mMessageTextView.getText() + showedMsg);

                }

    }

    }

    private StringformatDateTime(long time) {

    return new SimpleDateFormat("(HH:MM:ss)").format(new Date(time));

        }

    private void connectTCPServer() {

    Socket socket =null;

            while (socket ==null) {

    try {

    socket =new Socket("localhost", 8688);

                    mClientSocket = socket;

                    mPrintWriter =new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

                    mHandler.sendEmptyMessage(MESSAGE_SOCKET_CONNECTED);

                    System.out.println("connect server success");

                }catch (IOException e) {

    SystemClock.sleep(1000);

                    System.out.println("connect tcp server failed,retry... ");

                }

    }

    try {

    //接收服务器端的消息

                BufferedReader br =new BufferedReader(new InputStreamReader(socket.getInputStream()));

                while (!TCPClientActivity.this.isFinishing()) {

    String msg = br.readLine();

                    System.out.println("receive:" + msg);

                    if (msg !=null) {

    String time = formatDateTime(System.currentTimeMillis());

                        final String showedMsg ="server " + time +":" + msg +"\n";

                        mHandler.obtainMessage(MESSAGE_RECEIVE_NEW_MSG, showedMsg).sendToTarget();

                    }

    }

    System.out.println("quit...");

                mPrintWriter.close();

                br.close();

                socket.close();

            }catch (IOException e) {

    e.printStackTrace();

            }

    }

    }

    /** * 服务端代码 */

    public class TCPServerServiceextends Service {

    private boolean mIsServiceDestoryed =false;

        private String[]mDefinedMessages =new String[]{

    "你好啊,哈哈",

                "请问你叫什么名字",

                "今天深圳天气很好呀,shy",

                "你知道吗?我可是可以和多个人聊天的哦",

                "给你讲个笑话吧:据说爱笑的人运气不会太差,不知道真假。"

        };

        @Override

        public void onCreate() {

    new Thread(new TcpServer()).start();

            super.onCreate();

        }

    @Nullable

    @Override

        public IBinderonBind(Intent intent) {

    return null;

        }

    @Override

        public void onDestroy() {

    mIsServiceDestoryed =true;

            super.onDestroy();

        }

    private class TcpServerimplements Runnable {

    @Override

            public void run() {

    ServerSocket serverSocket =null;

                try {

    serverSocket =new ServerSocket(8688);

                }catch (IOException e) {

    System.err.println("establish tcp server failed,port:8688");

                    e.printStackTrace();

    return;

                }

    while (!mIsServiceDestoryed) {

    //接受客户顿请求

                    try {

    final Socket client = serverSocket.accept();

                        System.out.println("accept");

                        new Thread() {

    @Override

                            public void run() {

    try {

    responseClient(client);

                                }catch (IOException e) {

    e.printStackTrace();

                                }

    }

    }.start();

                    }catch (IOException e) {

    e.printStackTrace();

                    }

    }

    }

    }

    private void responseClient(Socket client)throws IOException {

    //用于接受客户端消息

            BufferedReader in =new BufferedReader(new InputStreamReader(client.getInputStream()));

            //用于向客户端发送消息

            PrintWriter out =new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);

            out.println("欢迎来到聊天室!");

            while (!mIsServiceDestoryed) {

    String str = in.readLine();

                System.out.println("msg from client:" + str);

                if (str ==null) {

    //客户端断开连接

                    break;

                }

    int i =new Random().nextInt(mDefinedMessages.length);

                String msg =mDefinedMessages[i];

                out.println(msg);

                System.out.println("send:" + msg);

            }

    System.out.println("client quit.");

            //关闭流

            in.close();

            out.close();

            client.close();

        }

    }

    相关文章

      网友评论

          本文标题:使用Socket

          本文链接:https://www.haomeiwen.com/subject/rofmjqtx.html