软件编程
位置:首页>> 软件编程>> Android编程>> Android聊天工具基于socket实现

Android聊天工具基于socket实现

作者:亓斌哥哥  发布时间:2021-12-06 04:40:01 

标签:Android,聊天,socket

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

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

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com