首先SocketService 服务端的代码:
/**
* Created by song on 2017/3/3 09:56
* 简易的聊天室:
* 首先是服务端,创建ServerSocket之后,循环调用accept的方法接收socket客户端
* 当有新的客户端介入,将socket加入到集合中,同时在线程池中新建一个线程!
* 再次将读写socket的操作放到自定义的线程中,
*
* 另外在读取信息的方法中,对输入字符串进行判断,如果为bye字符串,将socket从集合中 移除,然后close掉!
*
*/
public class Server {
//定义相关的参数,端口,存储Socket链接的集合,SeverSocket对象,线程池
private static final int port=12345;
private List<Socket> list=new ArrayList<>();
private ServerSocket serverSocket=null;
private ExecutorService executorService=null;//线程池
public static void main(String[] args) {
new Server();//创建ServerSocket
}
public Server(){
try {
serverSocket=new ServerSocket(port);
//创建线程池
executorService= Executors.newCachedThreadPool();
System.out.println("服务端运行中...\n");
Socket socket=null;
while (true){
socket=serverSocket.accept();
list.add(socket);
executorService.execute(new Service(socket));//在线程池中新开启一个线程
}
} catch (IOException e) {
e.printStackTrace();
}
}
private class Service implements Runnable {
private Socket socket;
private BufferedReader bufferedReader=null;
private String msg;
public Service(Socket socket) throws IOException {
this.socket=socket;
bufferedReader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
msg = "用户:" +this.socket.getInetAddress() + "~加入了聊天室"
+"当前在线人数:" +list.size();
this.sendmsg();
}
@Override
public void run() {
while(true){
try {
if((msg=bufferedReader.readLine())!=null){
if(msg.equals("bye")){
list.remove(socket);
bufferedReader.close();
msg = "用户:" + socket.getInetAddress()
+ "退出:" +"当前在线人数:"+list.size();
socket.close();
this.sendmsg();
break;
}else{
msg = socket.getInetAddress() + " 说: " + msg;
this.sendmsg();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//为连接上服务端的每个客户端发送信息
private void sendmsg() {
System.out.println(msg);
int num=list.size();
for (int i=0;i<num;i++){
Socket socket=list.get(i);
PrintWriter printWriter=null;
try {
printWriter=new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
printWriter.println(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
其次客户端的代码:
public class MainActivity extends AppCompatActivity {
//定义相关变量,完成初始化
private TextView txtshow;
private EditText editsend;
private Button btnsend;
private static final String HOST = "172.17.0.91";
private static final int PORT = 12345;
private Socket socket = null;
private BufferedReader in = null;
private PrintWriter out = null;
private String content = "";
private StringBuilder sb = null;
//定义一个handler对象,用来刷新界面
public Handler handler = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 0x123) {
sb.append(content);
txtshow.setText(sb.toString());
}
}
;
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sb = new StringBuilder();
txtshow = (TextView) findViewById(R.id.txtshow);
editsend = (EditText) findViewById(R.id.editsend);
btnsend = (Button) findViewById(R.id.btnsend);
//当程序一开始运行的时候就实例化Socket对象,与服务端进行连接,获取输入输出流
//因为4.0以后不能再主线程中进行网络操作,所以需要另外开辟一个线程
new Thread() {
public void run() {
try {
socket = new Socket(HOST, PORT);
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
socket.getOutputStream())), true);
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
//为发送按钮设置点击事件
btnsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String msg = editsend.getText().toString();
if (socket.isConnected()) {
if (!socket.isOutputShutdown()) {
out.println(msg);
}
}
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
if (socket.isConnected()) {
if (!socket.isInputShutdown()) {
if ((content = in.readLine()) != null) {
content += "\n";
handler.sendEmptyMessage(0x123);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
).start();
}
}
网友评论