Android的网络应用 - 简单的C/S聊天室

服务器端:提供两个类

创建ServerSocket监听的主类:MyServer.java

负责处理每个Socket通信的线程类:ServerThread.java

客户端:是一个Android应用程序

==>MultiThreadClient

界面提供两个文本框和一个发送按钮

Activity通过Handler来处理来自子线程的消息

客户端需要一个子线程负责读取来自网络的数据

项目效果:

Android的网络应用 - 简单的C/S聊天室_第1张图片

服务器端代码:

MyServer.java

import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;public class MyServer{//定义保存所有Socket的ArrayListpublic static ArrayList<Socket> socketList = new ArrayList<Socket>();    public static void main(String[] args) throws IOException    {        ServerSocket ss = new ServerSocket(8000);while(true){//此行代码会阻塞,将一直等待别人的连接Socket s = ss.accept();socketList.add(s);//每当客户端连接后启动一条ServerThread线程为该客户端服务new Thread(new ServerThread(s)).start();} 

ServerThrad.java

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;//负责处理每个线程通信的线程类public class ServerThread implements Runnable {//定义当前线程所处理的SocketSocket s = null;//该线程所处理的Socket所对应的输入流BufferedReader br = null;public ServerThread(Socket s)throws IOException{this.s = s;//初始化该Socket对应的输入流br = new BufferedReader(new InputStreamReader(s.getInputStream() , "utf-8"));   //②}public void run(){try{String content = null;//采用循环不断从Socket中读取客户端发送过来的数据while ((content = readFromClient()) != null){//遍历socketList中的每个Socket,//将读到的内容向每个Socket发送一次for (Socket s : MyServer.socketList){OutputStream os = s.getOutputStream();os.write((content + "\n").getBytes("utf-8"));}}}catch (IOException e){e.printStackTrace();}}//定义读取客户端数据的方法private String readFromClient(){try{return br.readLine();}//如果捕捉到异常,表明该Socket对应的客户端已经关闭catch (IOException e){//删除该Socket。MyServer.socketList.remove(s);    //①}return null;}}


客户端代码:

布局文件:main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"><LinearLayout android:orientation="horizontal"android:layout_width="fill_parent"android:layout_height="wrap_content"><!-- 定义一个文本框,它用于接受用户的输入 --><EditTextandroid:id="@+id/input"  android:layout_width="240px" android:layout_height="wrap_content" /><Buttonandroid:id="@+id/send"  android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="8px"android:text="@string/send"/></LinearLayout><!-- 定义一个文本框,它用于显示来自服务器的信息 --><EditTextandroid:id="@+id/show" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="top"android:editable="false" android:cursorVisible="false" /></LinearLayout>


Activity文件:MultiThreadClient.java

package org.wwj.net;import java.io.OutputStream;import java.net.Socket;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;public class MultiThreadClient extends Activity{// 定义界面上的两个文本框EditText input, show;// 定义界面上的一个按钮Button send;OutputStream os;Handler handler;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);input = (EditText) findViewById(R.id.input);send = (Button) findViewById(R.id.send);show = (EditText) findViewById(R.id.show);Socket s;handler = new Handler(){@Overridepublic void handleMessage(Message msg){// 如果消息来自于子线程if (msg.what == 0x123){// 将读取的内容追加显示在文本框中show.append("\n" + msg.obj.toString());}}};try{s = new Socket("183.30.181.228 ", 8000);// 客户端启动ClientThread线程不断读取来自服务器的数据new Thread(new ClientThread(s, handler)).start(); // ①os = s.getOutputStream();}catch (Exception e){e.printStackTrace();}send.setOnClickListener(new OnClickListener(){@Overridepublic void onClick(View v){try{// 将用户在文本框内输入的内容写入网络os.write((input.getText().toString() + "\r\n").getBytes("utf-8"));// 清空input文本框input.setText("");}catch (Exception e){e.printStackTrace();}}});}}


子线程类:ClientThread.java

package org.wwj.net;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.net.Socket;import android.os.Handler;import android.os.Message;public class ClientThread implements Runnable{//该线程负责处理的Socketprivate Socket s;private Handler handler;//该线程所处理的Socket所对应的输入流BufferedReader br = null;public ClientThread(Socket s , Handler handler)throws IOException{this.s = s;this.handler = handler;br = new BufferedReader(new InputStreamReader(s.getInputStream()));}public void run(){try{String content = null;//不断读取Socket输入流中的内容。while ((content = br.readLine()) != null){// 每当读到来自服务器的数据之后,发送消息通知程序界面显示该数据Message msg = new Message();msg.what = 0x123;msg.obj = content;handler.sendMessage(msg);}}catch (Exception e){e.printStackTrace();}}}


更多相关文章

  1. [Android]Thread线程入门3--多线程
  2. Android简单自定义布局介绍
  3. Android 自定义属性时TypedArray的使用方法
  4. 转帖并消化:Android中一种使用AttributeSet自定义控件的方法
  5. 客户端(android,ios)与服务器通信
  6. frameworks中增加自定义服务使其也成为系统服务
  7. Mqtt从服务端到Android客户端搭建(Android客户端搭建)

随机推荐

  1. 关于Android今后的发展的个人见解
  2. 22、从头学Android之Android的数据存储--
  3. Android(安卓)序列化之parcelable的简单
  4. android使用aidl实现进程间通信
  5. 使用c#开发的第一款APP的Android浏览器(创
  6. Android热补丁动态修复技术(完结篇):自动
  7. EPSON Printer 打印机 Sdk For Android
  8. 一篇看懂Android与Flutter之间的通信
  9. 史上最全面解析Android事件分发机制
  10. Android(安卓)JNI开发入门之一