从长连接流中,获取到服务端推得流,再进行解析
客户端代码:
/** * 主页面 */ 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
}
只需要打开服务即可,服务端死循环接受客户端的消息,接收到并推送给客户端,记录下有几个客户端连接,每个推送