android sock聊天工具,Android聊天工具基于socket实现

特简单, 没有数据库, 还没有处理各种异常。

登录:输入用户名点击的登录即可。

发送消息: 特定格式->toUser:message

1. 服务器:保存在线用户

public class Online {

private static Online mOnline = null;

private LinkedHashMap mOnlines = new LinkedHashMap();

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> mData = new ArrayList>();

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 temp = new HashMap();

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 temp = new HashMap();

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;

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值