首页 > 系统 > Android > 正文

Android聊天工具基于socket实现

2020-04-11 10:50:37
字体:
来源:转载
供稿:网友

特简单, 没有数据库, 还没有处理各种异常。
登录:输入用户名点击的登录即可。
发送消息: 特定格式->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:uidpublic 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;}

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表