TCP通信

  1. 注意不能在主线程中进行网络操作,不能在子线程更新UI。

  2. 活动的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff"
    android:orientation="vertical"
    android:padding="5dp" >

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/msg_container"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />
        </LinearLayout>
    </ScrollView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <EditText
            android:id="@+id/msg"
            android:layout_width="0dp"
            android:layout_height="35dp"
            android:layout_weight="1"
            android:background="@drawable/edit"
            android:ems="10"
            android:padding="5dp" />

        <Button
            android:id="@+id/send"
            android:layout_width="wrap_content"
            android:layout_height="35dp"
            android:enabled="false"
            android:text="发送" />
    </LinearLayout>

</LinearLayout>
  1. 服务端
public class TCPServerService extends Service {
    private static final String TAG = "TCPServerService";
    /**
     * 启动的线程已经脱离服务的主线程了,
     */
    private boolean mIsServerDestroyed = false;
    private String[] mDefinedMessages = new String[]{
            "你好呀,哈哈",
            "请问你叫什么名字",
            "今天的天气不错",
            "你知道吗,我可以和多个人聊天哦",
            "给你讲个笑话吧,据说爱笑的人运气不会太差,不知道真假"
    };

    @Override
    public void onCreate() {
        Log.d(TAG, "onCreate");
        super.onCreate();
        Log.d(TAG, "onCreate");
        new Thread(new TcpServer()).start();
    }

    public TCPServerService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onDestroy() {
        mIsServerDestroyed=true;
        super.onDestroy();
    }

    private class TcpServer implements Runnable{
        @Override
        public void run() {
            ServerSocket serverSocket = null;
            try{
                //建立服务器的端口
                serverSocket=new ServerSocket(8888);
            } catch (IOException e) {
                e.printStackTrace();
                Log.d(TAG, "establish tcp server failed, port:8888");
                return ;
            }
            if (serverSocket!=null){
                Log.d(TAG, "服务器端口成功...");
            }
            //如果没有服务没有被杀死
            while(!mIsServerDestroyed){
                try{
                    //得到和客户端的连接端口
                    final Socket client = serverSocket.accept();
                    Log.d(TAG, "accept socket");
                    new Thread(){
                        @Override
                        public void run() {
                            try{
                                //开个新的线程,在这个新的线程里面进行和客户的交流
                                responseClient(client);
                            }catch (IOException e){
                                e.printStackTrace();
                            }
                        }
                    }.start();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d(TAG, "连接失败");
                }
            }
        }
    }

    /**
     * 进行和客户端的交流
     * @param client 和客户端连接的端口
     * @throws IOException
     */
    private void responseClient(Socket client) throws IOException{
        BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
        PrintWriter out = new PrintWriter(new OutputStreamWriter(client.getOutputStream()));
        Log.d(TAG, out.toString());
        out.println("欢迎来到聊天室");
        out.flush();
        while(!mIsServerDestroyed){
            String str = in.readLine();
            Log.d(TAG, "msg from client:"+str);
            if (str == null){
                break;
            }
            int i = new Random().nextInt(mDefinedMessages.length);
            String msg = mDefinedMessages[i];
            out.println(msg);
            out.flush();
            Log.d(TAG, "send : "+msg);
        }
        Log.d(TAG, "client quit...");
        MyUtils.close(in);
        MyUtils.close(out);
        client.close();
    }
}
  1. 活动
public class TcpClientActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "TCPClientActivity";
    private static final int MSG_RECEIVE_NEW_MSG = 1;
    private static final int MSG_SOCKET_CONNECTED = 2;

    private Button mSendButton;
    private TextView mMessageTextView;
    private EditText mMessageEditText;

    private PrintWriter mPrintWriter;
    private Socket mClientSocket;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_RECEIVE_NEW_MSG:
                    mMessageTextView.setText(mMessageTextView.getText() + (String) msg.obj);
                    break;
                case MSG_SOCKET_CONNECTED:
                    mSendButton.setEnabled(true);
                    break;
                default:
                    break;
            }
            super.handleMessage(msg);
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tcp_client);
        Log.d(TAG, "onCreate");
        mMessageTextView = findViewById(R.id.msg_container);
        mSendButton = findViewById(R.id.send);
        mSendButton.setOnClickListener(this);
        mMessageEditText = findViewById(R.id.msg);
        Intent intent = new Intent(this, TCPServerService.class);
        startService(intent);
        Log.d(TAG, "onCreate");
        new Thread() {
            @Override
            public void run() {
                connectTCPServer();
            }
        }.start();
    }

    @Override
    protected void onDestroy() {
        if (mClientSocket != null) {
            try {
                //连接的关闭要先把流给杀死,然后才能关闭连接
                mClientSocket.shutdownInput();
                mClientSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        super.onDestroy();
    }

    private void connectTCPServer() {
        Socket socket = null;
        while (socket == null) {
            try {
                socket = new Socket("localhost", 8888);
                mClientSocket = socket;

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

            } catch (IOException e) {
                e.printStackTrace();
                SystemClock.sleep(1000);
                Log.d(TAG, "connect server failed, retry...");
            }

        }
        Log.d(TAG, "connect server success. ");
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    mClientSocket.getInputStream()
            ));

            Log.d(TAG, br.toString());
            while (!TcpClientActivity.this.isFinishing()) {
                Log.d(TAG, "qian");
                String msg = br.readLine();
                Log.d(TAG, "hou");
                Log.d(TAG, "receiver:" + msg);
                if (msg != null) {
                    String time = fromatDateTime(System.currentTimeMillis());
                    final String showMsg = "server " + time + ":" + msg + "\n";
                    mHandler.obtainMessage(MSG_RECEIVE_NEW_MSG, showMsg)
                            .sendToTarget();
                }
            }
            Log.d(TAG, "quit...");
            MyUtils.close(mPrintWriter);
            MyUtils.close(br);
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private String fromatDateTime(long time) {
        return new SimpleDateFormat("(HH:mm:ss)").format(new Date(time));
    }


    @Override
    public void onClick(View v) {
        if (v == mSendButton) {
            Log.d(TAG, "点击了");
            final String msg = mMessageEditText.getText().toString();
            if (!TextUtils.isEmpty(msg) && mPrintWriter != null) {
                new Thread(){
                    @Override
                    public void run() {
                        mPrintWriter.println(msg);
                    }
                }.start();
                mMessageEditText.setText("");
                String time = fromatDateTime(System.currentTimeMillis());
                final String showedMsg = "self" + time + ":" + msg + "\n";
                mMessageTextView.setText(mMessageTextView.getText() + showedMsg);
            }
        }
    }
}
此条目发表在未分类分类目录。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注