当前位置: 移动技术网 > 移动技术>移动开发>Android > Android聊天工具基于socket实现

Android聊天工具基于socket实现

2019年07月24日  | 移动技术网移动技术  | 我要评论

特简单, 没有数据库, 还没有处理各种异常。
登录:输入用户名点击的登录即可。
发送消息: 特定格式->touser:message
1. 服务器:保存在线用户    

public class online {
 private static online monline = null;
 private linkedhashmap<string, socket> monlines = new linkedhashmap<string, socket>();
  
 private online() {
 }
  
 public synchronized static online getinstance() {
  if(null == monline) {
   monline = new online();
  }
   
  return monline;
 }
  
 public void put(string key, socket socket) {
  if(!monlines.containskey(key)) {
   monlines.put(key, socket);
  }
 }
  
 public socket get(string key) {
  return monlines.get(key);
 }
  
 public void remove(string key) {
  monlines.remove(key);
 }
}

2. 服务器:一个简单的socket服务器    

import java.io.bufferedreader;
import java.io.ioexception;
import java.io.inputstreamreader;
import java.io.printwriter;
import java.net.serversocket;
import java.net.socket;
 
// login:uid
// send:fromuser:touser:message
// logout:uid
public class server implements runnable {
 private socket msocket;
 private online monline;
 
 public server(socket socket) {
  msocket = socket;
  monline = online.getinstance();
 }
 
 @override
 public void run() {
  try {
   bufferedreader reader = new bufferedreader(new inputstreamreader(
     msocket.getinputstream()));
   string cmd = reader.readline();
    
   // login
   if (cmd.startswith("login")) {
    string username = cmd.split(":")[1];
    monline.put(username, msocket);
    system.out.println(username + " login...");
     
    printwriter writer = new printwriter(msocket.getoutputstream());
    writer.println("success");
    writer.flush();
   } else if (cmd.startswith("send")) {
    system.out.println(cmd);
    string[] cmds = cmd.split(":");
    string from = cmds[1];
    socket to = monline.get(cmds[2]);
    string msg = cmds[3];
 
    printwriter writer = new printwriter(to.getoutputstream());
    system.out.println("rec:" + from + ":" + cmds[2] + ":" + msg);
     
    writer.println("rec:" + from + ":" + cmds[2] + ":" + msg);
    writer.flush();
   }else if (cmd.startswith("logout")) {
    system.out.println(cmd);
     
    string user = cmd.split(":")[1];
    monline.get(user).close();
    monline.remove(user);
     
    printwriter writer = new printwriter(msocket.getoutputstream());
    writer.println("success");
    writer.flush();
   }
  } catch (exception e) {
   e.printstacktrace();
  }
 }
 
 public static void main(string[] args) throws exception {
  serversocket server = new serversocket(8888);
  boolean flag = true;
  while (flag) {
   new thread(new server(server.accept())).start();
   system.out.println("user in...");
  }
 
  server.close();
 }
}

3. 客户端登录界面    

public class mainactivity extends activity {
 private edittext muser;
  
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
   
  muser = (edittext) findviewbyid(r.id.username);
 }
  
 public void login(view view) {
  final string username = muser.gettext().tostring().trim();
  login login = new login(username);
  login.setonloginlistener(new login.logincallback() {
   @override
   public void onlogin(boolean success) {
    if(success) {
     intent intent = new intent(mainactivity.this, chat.class);
     intent.putextra("user", username);
     startactivity(intent);
     finish();
    }else {
     toast.maketext(mainactivity.this, "登录失败", toast.length_short).show();
    }
   }
  });
   
  login.login();
 }
}

4. 处理登录    

public class login {
 private string musername;
 private logincallback mcallback;
  
 public login(string username) {
  musername = username;
 }
  
 public void setonloginlistener(logincallback callback) {
  mcallback = callback;
 }
  
 private handler mhandler = new handler() {
  public void handlemessage(message msg) {
   switch (msg.what) {
   case constant.success:
    mcallback.onlogin(true);
    break;
   case constant.failed:
    mcallback.onlogin(false);
    break;
   }
  };
 };
  
 public void login() {
  new thread(new runnable() {
   @override
   public void run() {
    socket socket = null;
    try {
     socket = new socket();
     socket.connect(new inetsocketaddress("192.168.100.100", 8888), 4000);
     printwriter writer = new printwriter(socket.getoutputstream());
     writer.println("login:" + musername);
     writer.flush();
      
     bufferedreader reader = new bufferedreader(
       new inputstreamreader(socket.getinputstream()));
     string line = reader.readline();
     system.out.println(line);
     if("success".equals(line)) {
      pconnection.socket = socket;
      mhandler.sendemptymessage(constant.success);
     }else {
      mhandler.sendemptymessage(constant.failed);
     }
    }catch(exception e) {
     e.printstacktrace();
    }
   }
  }).start();
 }
  
 public interface logincallback {
  public void onlogin(boolean success);
 }
}

5. 聊天界面    

public class chat extends activity {
 private string musername;
 private edittext medit;
 private listview mmessage;
  
 private receivermessage mrecmessage;
 private sendmessage msendmesage;
 private list<map<string, string>> mdata = new arraylist<map<string, string>>();
 private messagesadapter madapter;
  
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.chat_layout);
   
  musername = getintent().getstringextra("user");
  medit = (edittext) findviewbyid(r.id.edit);
  mmessage = (listview) findviewbyid(r.id.message);
   
  mrecmessage = new receivermessage();
  mrecmessage.setonreceiverlistener(new reclistener());
  mrecmessage.run();
   
  msendmesage = new sendmessage();
  msendmesage.setonsendlistener(new sendlistener());
   
  madapter = new messagesadapter(this, mdata);
  mmessage.setadapter(madapter);
 }
  
 public void send(view view) {
  string[] content = medit.gettext().tostring().trim().split(":");
  msendmesage.send(musername, content[0], content[1]);
 }
  
 private class reclistener implements receivermessage.onreceiverlistener {
  @override
  public void onreceiver(string user, string msg) {
   map<string, string> temp = new hashmap<string, string>();
   temp.put("user", user);
   temp.put("msg", msg);
   temp.put("pos", "right");
   mdata.add(temp);
   madapter.notifydatasetchanged();
  }
 }
  
 private class sendlistener implements sendmessage.onsendlistener {
  @override
  public void onsend(string[] msg) {
   map<string, string> temp = new hashmap<string, string>();
   temp.put("user", "我");
   temp.put("msg", msg[1]);
   temp.put("pos", "left");
   mdata.add(temp);
   madapter.notifydatasetchanged();
  }
 }
  
 @override
 public boolean onoptionsitemselected(menuitem item) {
  if(r.id.logout == item.getitemid()) {
   logout logout = new logout();
   logout.setonlogoutlistener(new logout.onlogoutlistener() {
    @override
    public void onlogout(boolean success) {
     if(success) {
      toast.maketext(chat.this, "注销成功", toast.length_short).show();
      finish();
     }else {
      toast.maketext(chat.this, "注销失败", toast.length_short).show();
     }
    }
   });
    
   logout.logout(musername);
  }
   
  return super.onoptionsitemselected(item);
 }
  
 @override
 public boolean oncreateoptionsmenu(menu menu) {
  getmenuinflater().inflate(r.menu.main, menu);
  return super.oncreateoptionsmenu(menu);
 }
}

6. 发送消息    

public class sendmessage {
 private onsendlistener mlistener;
  
 public void setonsendlistener(onsendlistener listener) {
  mlistener = listener;
 }
  
 private handler mhandler = new handler() {
  public void handlemessage(message msg) {
   mlistener.onsend((string[]) msg.obj);
  };
 };
  
 // send:from:to:message
 public void send(final string from , final string to, final string msg) {
  new thread(new runnable() {
   @override
   public void run() {
    socket socket = null;
    try {
     socket = new socket();
     socket.connect(new inetsocketaddress("192.168.100.100", 8888), 4000);
     printwriter writer = new printwriter(socket.getoutputstream());
     writer.println("send:" + from + ":" + to + ":" + msg);
     writer.flush();
      
     message message = mhandler.obtainmessage(
       constant.success, new string[] {to, msg});
      
     message.sendtotarget();
    } catch(exception e) {
    } finally {
     try {
      socket.close();
     } catch (ioexception e) {
      e.printstacktrace();
     }
    }
   }
  }).start();
 }
  
 public interface onsendlistener {
  public void onsend(string[] msg);
 }
}

7. 接收消息,死循环,但阻塞,没啥问题    

public class receivermessage {
 private onreceiverlistener mlistener;
 public void setonreceiverlistener(onreceiverlistener listener) {
  mlistener = listener;
 }
  
 private handler mhandler = new handler() {
  public void handlemessage(message msg) {
   string[] cmds = (string[]) msg.obj;
   mlistener.onreceiver(cmds[0], cmds[1]);
  };
 };
  
 public void run() {
  new thread(new runnable() {
   @override
   public void run() {
    try {
     socket socket = pconnection.socket;
     while(true) {
      system.out.println("wait for message...");
      bufferedreader reader = new bufferedreader(
        new inputstreamreader(socket.getinputstream()));
      string line = reader.readline();
       
      if(line.startswith("rec")) {
       //rec:fromuser:touser:message
       string[] cmds = line.split(":");
       system.out.println(cmds[0] + ":" + cmds[1] + ":" + cmds[2] + ":" + cmds[3]);
       message msg = mhandler.obtainmessage(constant.success, new string[] {cmds[1], cmds[3]});
       msg.sendtotarget();
      }
     }
    } catch (exception e) {
     e.printstacktrace();
    }
   }
  }).start();
 }
  
 public interface onreceiverlistener {
  public void onreceiver(string user, string msg);
 }
}

8. 注销登录    

public class logout {
 public onlogoutlistener mlistener;
  
 public void setonlogoutlistener(onlogoutlistener listner) {
  mlistener = listner;
 }
  
 private handler mhandler = new handler() {
  public void handlemessage(message msg) {
   if(constant.success == msg.what) {
    mlistener.onlogout(true);
   }else {
    mlistener.onlogout(false);
   }
  };
 };
  
 public void logout(final string user) {
  new thread(new runnable() {
   @override
   public void run() {
    try {
     socket socket = new socket();
     socket.connect(new inetsocketaddress("192.168.100.100", 8888), 4000);
     printwriter writer = new printwriter(socket.getoutputstream());
     writer.println("logout:" + user);
     writer.flush();
      
     bufferedreader reader = new bufferedreader(
       new inputstreamreader(socket.getinputstream()));
      
     if("success".equals(reader.readline())) {
      pconnection.socket = null;
      mhandler.sendemptymessage(constant.success);
     }else {
      mhandler.sendemptymessage(constant.failed);
     }
    } catch (exception e) {
     e.printstacktrace();
    }
   }
  }).start();
 }
  
 public interface onlogoutlistener {
  public void onlogout(boolean success);
 }
}

9. 存放登录后的socket,在发送消息和接收消息时使用该socket    

public class pconnection {
 public static socket socket;
}

希望本文所述对大家学习有所帮助。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网