废话不多说,直接上代码,这是一个自动回复的聊天室。首先是服务端的,这个服务端的ServerSocket 我用一个服务Service来写(本人详细标注注解,大家直接看注解即可),并且设置到一个单独的线程中,当然本demo 出自Android开发艺术探索 。毕竟我们学习最快的捷径就是站在巨人的肩膀上学习。
public class TCPServerService extends Service { // 这个是判断是否进入死亡或者销毁状态的标志。 private boolean mIsServiceDestoryed = false; // 自动回复返回的文字 private String[] mDefinedMessages = new String[] { "你好啊,哈哈", "请问你叫什么名字呀?", "今天北京天气不错啊,shy", "你知道吗?我可是可以和多个人同时聊天的哦", "给你讲个笑话吧:据说爱笑的人运气不会太差,不知道真假。" }; @Override public void onCreate() { // 启动的时候执行线程 TcpServer new Thread(new TcpServer()).start(); super.onCreate(); } @Override public IBinder onBind(Intent intent) { return null; } // 死亡或者销毁的时候 设置mIsServiceDestoryed @Override public void onDestroy() { mIsServiceDestoryed = true; super.onDestroy(); } // 实现一个Runnable 重写run 我们看run 中代码 private class TcpServer implements Runnable { @Override public void run() { // 首先声明一个ServerSocket ServerSocket serverSocket = null; try { // 创建ServerSocket 设置port 端口8668 serverSocket = new ServerSocket(8688); } catch (IOException e) { System.err.println("establish tcp server failed, port:8688"); e.printStackTrace(); return; } while (!mIsServiceDestoryed){ try { // 接受客户端请求 没有接收到消息的时候会阻塞 等待这个方法 final Socket clientsocket = serverSocket.accept(); System.out.println("accept:接受到了客户端"); new Thread(){ @Override public void run() { try { // 执行回复消息方法 responseClient(clientsocket); } catch (IOException e) { e.printStackTrace(); } } }.start(); } catch (IOException e) { e.printStackTrace(); } } } } // 传入的参数是客户端的socket private void responseClient(Socket client) throws IOException { // 用于接收客户端消息 client.getInputStream() 输入流 BufferedReader in = new BufferedReader(new InputStreamReader( client.getInputStream())); // 用于向客户端发送消息 client.getOutputStream() 输出流 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; } // 有消息回复 上面定义String 的句子 int i = new Random().nextInt(mDefinedMessages.length); String msg = mDefinedMessages[i]; out.println(msg); System.out.println("send :" + msg); } System.out.println("client quit."); // 关闭流 MyUtils.close(out); MyUtils.close(in); client.close(); } }
以上就是服务端的代码,很简洁。只是一个自动回复的简单demo。那么我们接下来看客户端的。
public class MainActivity extends AppCompatActivity implements View.OnClickListener { // 判断标识符 设置textview 聊天内容 private static final int MESSAGE_RECEIVE_NEW_MSG = 1; // 如果连接成功 给发送按键设置成可点击状态,默认是不可点击 private static final int MESSAGE_SOCKET_CONNECTED = 2; private Button mSendButton; private TextView mMessageTextView; private EditText mMessageEditText; private PrintWriter mPrintWriter; private Socket mClientSocket; @SuppressLint("HandlerLeak") private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case MESSAGE_RECEIVE_NEW_MSG: { // 判断标识符 设置textview 聊天内容 mMessageTextView.setText(mMessageTextView.getText() + (String) msg.obj); break; } case MESSAGE_SOCKET_CONNECTED: { // 如果连接成功 给发送按键设置成可点击状态,默认是不可点击 mSendButton.setEnabled(true); break; } default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mMessageTextView = (TextView) findViewById(R.id.msg_container); mSendButton = (Button) findViewById(R.id.send); mSendButton.setOnClickListener(this); mMessageEditText = (EditText) findViewById(R.id.msg); Intent service = new Intent(this, TCPServerService.class); // 启动服务端 startService(service); new Thread() { @Override public void run() { // 调用连接ServerSocket ! 这里一定要在线程中使用哦,因为是耗时操作。 connectTCPServer(); } }.start(); } @Override protected void onDestroy() { if (mClientSocket != null) { try { // 注意这个方法,是单向断开连接,而socket 连接还是存在的。 mClientSocket.shutdownInput(); mClientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } super.onDestroy(); } // 发送按钮方法 @Override public void onClick(View v) { if (v == mSendButton) { // 获取输入的值 final String msg = mMessageEditText.getText().toString(); // 判断值是否是空的,输出流是否是空的。如果不是就发送 if (!TextUtils.isEmpty(msg) && mPrintWriter != null) { new Thread(){ @Override public void run() { mPrintWriter.println(msg); super.run(); } }.start(); mMessageEditText.setText(""); String time = formatDateTime(System.currentTimeMillis()); final String showedMsg = "self " + time + ":" + msg + "\n"; mMessageTextView.setText(mMessageTextView.getText() + showedMsg); } } } @SuppressLint("SimpleDateFormat") private String formatDateTime(long time) { return new SimpleDateFormat("(HH:mm:ss)").format(new Date(time)); } private void connectTCPServer() { // 声明一个客户端的socket Socket socket = null; while (socket == null) { try { // 创建客户端socket 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 (!MainActivity.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..."); // 断开连接 MyUtils.close(mPrintWriter); MyUtils.close(br); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }