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