2021.6.6 android开发之简单聊天室
一、今日学习内容
android开发之简单聊天室
前文
本文将介绍怎么使用socket阻塞通信结合多线程来实现一个简单的聊天室。
我这里是用java写的一个服务器端,用android写的客户端。
1.TCP服务器端实现
直接上代码
1.主代码
主代码主要实现了通道(这里本人定义了一个线程类来实现信息的发送和接受)的链接,发送和接受信息,然后通过发送过来的消息来判断是群发还是私发,当中的逻辑实现,各位自己看代码就成,!!!!
package com.TCP;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/* * MyServer类,用于监听客户端Socket连接请求 */
public class server {
private List<Mychannel> channellist = new ArrayList<Mychannel>();
public static void main(String[] args) throws IOException {
new server().start();
}
public void start() throws IOException{
@SuppressWarnings("resource")
ServerSocket serverSocket = new ServerSocket(8888);
System.out.println("服务器启动!!!");
while(true){
Socket socket = serverSocket.accept();
System.out.println(socket.toString()+"已连接");
Mychannel mychannel = new Mychannel(socket);
channellist.add(mychannel);
new Thread(mychannel).start();
}
}
/**
* 一个客户一个通道
* @author
*
*/
public class Mychannel implements Runnable{
private DataInputStream dis;
private DataOutputStream dos;
private boolean isRunning = true;
private String name;
public Mychannel(Socket socket){
try {
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
this.name = dis.readUTF();
sendohters(this.name+"已上线"+"\n");
System.out.println(this.name);
} catch (IOException e) {
//e.printStackTrace();
CloseUtil.closeAll(dis,dos);
isRunning = false;
}
}
//读取数据
private String receive(){
String content = "";
try {
content = dis.readUTF();
System.out.println("读取的数据:"+content);
} catch (IOException e) {
//e.printStackTrace();
System.out.println("读取数据出现错误!");
CloseUtil.closeAll(dis,dos);
isRunning = false;
channellist.remove(this);
}
return content;
}
//发送数据
private void send(String content){
if(content==null||content.equals("")){
return ;
}
try {
dos.writeUTF(packMessage(content));
System.out.println("发送的数据:"+packMessage(content));
} catch (IOException e) {
//e.printStackTrace();
System.out.println("发送数据出现错误!");
CloseUtil.closeAll(dis,dos);
isRunning = false;
channellist.remove(this);
}
}
//发送数据给其他客户端
private void sendohters(String content){
if(content.indexOf("/")>-1){
String name = getname(content);
for(Mychannel other:channellist){
if(other.name.equals(name)){
other.send(content);
}
}
}else{
for(Mychannel other:channellist){
other.send(content);
}
}
}
//得到目标人物的名称
private String getname(String content){
String name = null;
int Pbegin = content.indexOf("/");
int Pend = content.indexOf(".");
name = content.substring(Pbegin+1,Pend);
return name;
}
//运行
public void run() {
while(isRunning){
sendohters(this.receive());
}
}
/** 对要广播的数据进行包装*/
private String packMessage(String content) {
String msg = null;
String time = null;
String Pcontent = null;
/*int begin = content.indexOf("<");
int end = content.indexOf(">");*/
int Pbegin = content.indexOf("/");
int Pend = content.indexOf(".");
if(Pbegin>-1&&Pend>-1){
Pcontent = content.substring(Pend+1);
time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
msg = "<"+this.name+">"+" "+time+"\n"+"-"+this.name+"悄悄的和你说:"+Pcontent+"\n";
}
else{
/*name = content.substring(begin,end+1);
content = content.substring(end+1);*/
time = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());
msg = "<"+this.name+">" + " " + time +"\n"+"内容为(群发):"+ content + "\n";
}
//System.out.println("有几个客户端运行几次packMessage" + msg);
return msg;
}
}
}
2.相关工具类
CloseUtil类用来关闭流,有一定java基础的应该都看得懂!!!!
package com.TCP;
import java.io.Closeable;
import java.io.IOException;
public class CloseUtil {
public static void closeAll(Closeable...io) {
for (Closeable temp:io) {
if(null!=temp) {
try {
temp.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
User类是用户的工具类
package com.TCP;
import com.TCP.server.Mychannel;
/**
* Created by littlecurl 2018/6/24
*/
public class User {
private String name; //用户名
private Mychannel channel; //密码
public User(Mychannel channel, String name) {
this.channel = channel;
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Mychannel getChannel() {
return channel;
}
public void setChannel(Mychannel channel) {
this.channel = channel;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", password='" + channel + '\'' +
'}';
}
}
原文链接:https://blog.csdn.net/a_ittle_pan/article/details/107427980