从长连接流中,获取到服务端推得流,再进行解析

客户端代码:

/**
 * 主页面
 */
public class HomeActivity extends Activity {


    private EditText mEditText; //用于输入要发送的内容
    private Button mSend; //发送按钮

    private RecyclerView mListMessage;
    private HomeAdapter mHomeAdapter;
    private List<String> mData = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        overridePendingTransition(R.anim.slide_in_left, 0);
        initView();
        setRecyclerView();
        connect();//连接
    }

    @Override
    public void finish() {
        super.finish();
        overridePendingTransition(0, R.anim.slide_in_left);
    }

    private void initView() {
        mListMessage = (RecyclerView) findViewById(R.id.rlv_message_list);
        mEditText = (EditText) findViewById(R.id.edit);
        mSend = (Button) findViewById(R.id.send);
        mSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //发送
                send();
            }
        });
    }

    private void setRecyclerView() {
        mListMessage.setLayoutManager(new LinearLayoutManager(this));
        mHomeAdapter = new HomeAdapter(this);
        mListMessage.setAdapter(mHomeAdapter);
        mListMessage.setItemAnimator(new DefaultItemAnimator());
    }

    /**
     * 设置adapter消息更改,并滚到最底部
     *
     * @param message
     */
    private void setHomeAdapterDataChanged(String message) {
        mData.add(message);
        mHomeAdapter.setData(mData);
        mListMessage.scrollToPosition(mData.size());
    }
    /*
     * -----------------------------分割线-------------------------------------------
    */

    Socket socket = null;
    BufferedWriter writer = null;
    BufferedReader reader = null;


    public void connect() {
        /*
         * AsyncTask是异步通信,在子线程中处理任务
       */
        //(4)这个AsyncTask用于从网络读取数据,注意是大写的Void
        AsyncTask<Void, String, Void> read = new AsyncTask<Void, String, Void>() {
            @Override
            protected Void doInBackground(Void... params) {
                try {
                    //(1)第一个参数是服务器的IP地址;第二个参数是服务器的端口号
                    socket = new Socket(HttpConstant.SOCKET_PATH, HttpConstant.SOCKET_PORT);

                    //(2)将socket中的OutputStream逐步封装成BufferedWriter
                    writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "gbk"));

                    //(3)将socket中的InputStream逐步封装成BufferedReader
                    reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), "gbk"));

                    publishProgress("@success");
                } catch (UnknownHostException e) {
                    Toast.makeText(HomeActivity.this, "无法建立连接", Toast.LENGTH_SHORT).show();
                } catch (IOException e) {
                    Toast.makeText(HomeActivity.this, "无法建立连接", Toast.LENGTH_SHORT).show();
                }

            /*
                 * -----------接下来就可以使用线程控制当前数据的读写了------------
             */
                try {
                    String line;
                    while ((line = reader.readLine()) != null) { //如果还能读出数据
                        publishProgress(line); //实际上是把这个数据传入到onProgressUpdate()方法中进行处理
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(String... values) {
                if (values[0].equals("@success")) {
                    Toast.makeText(HomeActivity.this, "连接成功", Toast.LENGTH_SHORT).show();
                }
                //接收到传进来的line中的字符串后,保存在values数组的第一个下标里面
                setHomeAdapterDataChanged(values[0]);
                //mText.append(values[0] + "\n");
//                mText.append("服务器返回:" + s + "\n");

                super.onProgressUpdate(values);
            }
        };

        //(5)将AsyncTask类的对象,用execute()方法开始执行
        read.execute();

    }//connect()方法结束


    public void send() {
        try {
            //如果是想在Android客户端中看到自己发的东西,就加上这一句
//            mText.append("我说:" + mEditText.getText().toString() + "\n");
            //现在把数据输出到服务器。注意,这里是很容易出问题的点,要加上 \n
            writer.write("游客:" + mEditText.getText().toString() + "\n");
            //还要调用flush()方法将数据强制输出
            writer.flush();
            mEditText.setText("");
        } catch (IOException e) {
            e.printStackTrace();
        }


    }//send()方法结束

}



package com.tywl.chatroom.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.tywl.chatroom.R;

import java.util.ArrayList;
import java.util.List;

/**
 * 首页对话列表adapter
 */
public class HomeAdapter extends RecyclerView.Adapter<HomeAdapter.MyViewHolder> {

    private Context mContext;
    private List<String> mData = new ArrayList<>();

    public HomeAdapter(Context context) {
        mContext = context;
    }

    public void setData(List<String> list) {
        mData = (list != null) ? list : new ArrayList<String>();
        notifyDataSetChanged();
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(mContext).inflate(
                R.layout.item_home, parent, false));
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.tv.setText(mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView tv;

        public MyViewHolder(View view) {
            super(view);
            tv = (TextView) view.findViewById(R.id.tv_home_adapter_title);
        }
    }
}



服务端代码:

package testSocket;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;


/*
 * MyServer类,用于监听客户端Socket连接请求
 */
public class MyServer {


// 定义ServerSocket的端口号
private static final int SOCKET_PORT = 50001;
// 使用ArrayList存储所有的Socket
public static ArrayList<Socket> socketList = new ArrayList<Socket>();


public static void main(String[] args) {
MyServer myServer = new MyServer();
myServer.initMyServer();
}


public void initMyServer() {
try {
// 创建一个ServerSocket,用于监听客户端Socket的连接请求
ServerSocket serverSocket = new ServerSocket(SOCKET_PORT);
while (true) {
// 每当接收到客户端的Socket请求,服务器端也相应的创建一个Socket
Socket socket = serverSocket.accept();
socketList.add(socket);
// 每连接一个客户端,启动一个ServerThread线程为该客户端服务
new Thread(new ServerThread(socket)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}


/*
* ServerThread类,用于给客户端推送消息
*/
class ServerThread implements Runnable {
private Socket socket = null;
private BufferedReader bufferedReader = null;


public ServerThread(Socket socket) throws IOException {
this.socket = socket;
// 获取该socket对应的输入流
bufferedReader = new BufferedReader(new InputStreamReader(
socket.getInputStream(), "gbk"));
}


public void run() {
try {
String content = null;
// 采用循环不断地从Socket中读取客户端发送过来的数据
while ((content = bufferedReader.readLine()) != null) {
// 将读到的内容向每个Socket发送一次
System.out.println("run()=" + content);
for (Socket socket : MyServer.socketList) {
// 获取该socket对应的输出流
PrintStream printStream = new PrintStream(
socket.getOutputStream());
// 向该输出流中写入要广播的内容
printStream.println(packMessage(content));
}
}
} catch (IOException e) {
e.printStackTrace();
}
}


/*
* 对要广播的数据进行包装
*/
private String packMessage(String content) {
String result = null;
SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss"); // 设置日期格式
result = "   " + content + "      " + df.format(new Date());
System.out.println("有几个客户端运行几次packMessage" + result);
return result;
}


}// ServerThread end
}

只需要打开服务即可,服务端死循环接受客户端的消息,接收到并推送给客户端,记录下有几个客户端连接,每个推送