Android聊天工具基于socket实现
特简单,没有数据库,还没有处理各种异常。
登录:输入用户名点击的登录即可。
发送消息:特定格式->toUser:message
1.服务器:保存在线用户
publicclassOnline{
privatestaticOnlinemOnline=null;
privateLinkedHashMap<String,Socket>mOnlines=newLinkedHashMap<String,Socket>();
privateOnline(){
}
publicsynchronizedstaticOnlinegetInstance(){
if(null==mOnline){
mOnline=newOnline();
}
returnmOnline;
}
publicvoidput(Stringkey,Socketsocket){
if(!mOnlines.containsKey(key)){
mOnlines.put(key,socket);
}
}
publicSocketget(Stringkey){
returnmOnlines.get(key);
}
publicvoidremove(Stringkey){
mOnlines.remove(key);
}
}
2.服务器:一个简单的socket服务器
importjava.io.BufferedReader;
importjava.io.IOException;
importjava.io.InputStreamReader;
importjava.io.PrintWriter;
importjava.net.ServerSocket;
importjava.net.Socket;
//login:uid
//send:fromuser:touser:message
//logout:uid
publicclassServerimplementsRunnable{
privateSocketmSocket;
privateOnlinemOnline;
publicServer(Socketsocket){
mSocket=socket;
mOnline=Online.getInstance();
}
@Override
publicvoidrun(){
try{
BufferedReaderreader=newBufferedReader(newInputStreamReader(
mSocket.getInputStream()));
Stringcmd=reader.readLine();
//login
if(cmd.startsWith("login")){
StringuserName=cmd.split(":")[1];
mOnline.put(userName,mSocket);
System.out.println(userName+"login...");
PrintWriterwriter=newPrintWriter(mSocket.getOutputStream());
writer.println("success");
writer.flush();
}elseif(cmd.startsWith("send")){
System.out.println(cmd);
String[]cmds=cmd.split(":");
Stringfrom=cmds[1];
Socketto=mOnline.get(cmds[2]);
Stringmsg=cmds[3];
PrintWriterwriter=newPrintWriter(to.getOutputStream());
System.out.println("rec:"+from+":"+cmds[2]+":"+msg);
writer.println("rec:"+from+":"+cmds[2]+":"+msg);
writer.flush();
}elseif(cmd.startsWith("logout")){
System.out.println(cmd);
Stringuser=cmd.split(":")[1];
mOnline.get(user).close();
mOnline.remove(user);
PrintWriterwriter=newPrintWriter(mSocket.getOutputStream());
writer.println("success");
writer.flush();
}
}catch(Exceptione){
e.printStackTrace();
}
}
publicstaticvoidmain(String[]args)throwsException{
ServerSocketserver=newServerSocket(8888);
booleanflag=true;
while(flag){
newThread(newServer(server.accept())).start();
System.out.println("userin...");
}
server.close();
}
}
3.客户端登录界面
publicclassMainActivityextendsActivity{
privateEditTextmUser;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mUser=(EditText)findViewById(R.id.username);
}
publicvoidlogin(Viewview){
finalStringuserName=mUser.getText().toString().trim();
Loginlogin=newLogin(userName);
login.setOnLoginListener(newLogin.LoginCallback(){
@Override
publicvoidonLogin(booleansuccess){
if(success){
Intentintent=newIntent(MainActivity.this,Chat.class);
intent.putExtra("user",userName);
startActivity(intent);
finish();
}else{
Toast.makeText(MainActivity.this,"登录失败",Toast.LENGTH_SHORT).show();
}
}
});
login.login();
}
}
4.处理登录
publicclassLogin{
privateStringmUserName;
privateLoginCallbackmCallback;
publicLogin(StringuserName){
mUserName=userName;
}
publicvoidsetOnLoginListener(LoginCallbackcallback){
mCallback=callback;
}
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
switch(msg.what){
caseConstant.SUCCESS:
mCallback.onLogin(true);
break;
caseConstant.FAILED:
mCallback.onLogin(false);
break;
}
};
};
publicvoidlogin(){
newThread(newRunnable(){
@Override
publicvoidrun(){
Socketsocket=null;
try{
socket=newSocket();
socket.connect(newInetSocketAddress("192.168.100.100",8888),4000);
PrintWriterwriter=newPrintWriter(socket.getOutputStream());
writer.println("login:"+mUserName);
writer.flush();
BufferedReaderreader=newBufferedReader(
newInputStreamReader(socket.getInputStream()));
Stringline=reader.readLine();
System.out.println(line);
if("success".equals(line)){
PConnection.socket=socket;
mHandler.sendEmptyMessage(Constant.SUCCESS);
}else{
mHandler.sendEmptyMessage(Constant.FAILED);
}
}catch(Exceptione){
e.printStackTrace();
}
}
}).start();
}
publicinterfaceLoginCallback{
publicvoidonLogin(booleansuccess);
}
}
5.聊天界面
publicclassChatextendsActivity{
privateStringmUserName;
privateEditTextmEdit;
privateListViewmMessage;
privateReceiverMessagemRecMessage;
privateSendMessagemSendMesage;
privateList<Map<String,String>>mData=newArrayList<Map<String,String>>();
privateMessagesAdaptermAdapter;
@Override
protectedvoidonCreate(BundlesavedInstanceState){
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=newReceiverMessage();
mRecMessage.setOnReceiverListener(newRecListener());
mRecMessage.run();
mSendMesage=newSendMessage();
mSendMesage.setOnSendListener(newSendListener());
mAdapter=newMessagesAdapter(this,mData);
mMessage.setAdapter(mAdapter);
}
publicvoidsend(Viewview){
String[]content=mEdit.getText().toString().trim().split(":");
mSendMesage.send(mUserName,content[0],content[1]);
}
privateclassRecListenerimplementsReceiverMessage.OnReceiverListener{
@Override
publicvoidonReceiver(Stringuser,Stringmsg){
Map<String,String>temp=newHashMap<String,String>();
temp.put("user",user);
temp.put("msg",msg);
temp.put("pos","right");
mData.add(temp);
mAdapter.notifyDataSetChanged();
}
}
privateclassSendListenerimplementsSendMessage.OnSendListener{
@Override
publicvoidonSend(String[]msg){
Map<String,String>temp=newHashMap<String,String>();
temp.put("user","我");
temp.put("msg",msg[1]);
temp.put("pos","left");
mData.add(temp);
mAdapter.notifyDataSetChanged();
}
}
@Override
publicbooleanonOptionsItemSelected(MenuItemitem){
if(R.id.logout==item.getItemId()){
Logoutlogout=newLogout();
logout.setOnLogoutListener(newLogout.OnLogoutListener(){
@Override
publicvoidonLogout(booleansuccess){
if(success){
Toast.makeText(Chat.this,"注销成功",Toast.LENGTH_SHORT).show();
finish();
}else{
Toast.makeText(Chat.this,"注销失败",Toast.LENGTH_SHORT).show();
}
}
});
logout.logout(mUserName);
}
returnsuper.onOptionsItemSelected(item);
}
@Override
publicbooleanonCreateOptionsMenu(Menumenu){
getMenuInflater().inflate(R.menu.main,menu);
returnsuper.onCreateOptionsMenu(menu);
}
}
6.发送消息
publicclassSendMessage{
privateOnSendListenermListener;
publicvoidsetOnSendListener(OnSendListenerlistener){
mListener=listener;
}
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
mListener.onSend((String[])msg.obj);
};
};
//send:from:to:message
publicvoidsend(finalStringfrom,finalStringto,finalStringmsg){
newThread(newRunnable(){
@Override
publicvoidrun(){
Socketsocket=null;
try{
socket=newSocket();
socket.connect(newInetSocketAddress("192.168.100.100",8888),4000);
PrintWriterwriter=newPrintWriter(socket.getOutputStream());
writer.println("send:"+from+":"+to+":"+msg);
writer.flush();
Messagemessage=mHandler.obtainMessage(
Constant.SUCCESS,newString[]{to,msg});
message.sendToTarget();
}catch(Exceptione){
}finally{
try{
socket.close();
}catch(IOExceptione){
e.printStackTrace();
}
}
}
}).start();
}
publicinterfaceOnSendListener{
publicvoidonSend(String[]msg);
}
}
7.接收消息,死循环,但阻塞,没啥问题
publicclassReceiverMessage{
privateOnReceiverListenermListener;
publicvoidsetOnReceiverListener(OnReceiverListenerlistener){
mListener=listener;
}
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
String[]cmds=(String[])msg.obj;
mListener.onReceiver(cmds[0],cmds[1]);
};
};
publicvoidrun(){
newThread(newRunnable(){
@Override
publicvoidrun(){
try{
Socketsocket=PConnection.socket;
while(true){
System.out.println("waitformessage...");
BufferedReaderreader=newBufferedReader(
newInputStreamReader(socket.getInputStream()));
Stringline=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]);
Messagemsg=mHandler.obtainMessage(Constant.SUCCESS,newString[]{cmds[1],cmds[3]});
msg.sendToTarget();
}
}
}catch(Exceptione){
e.printStackTrace();
}
}
}).start();
}
publicinterfaceOnReceiverListener{
publicvoidonReceiver(Stringuser,Stringmsg);
}
}
8.注销登录
publicclassLogout{
publicOnLogoutListenermListener;
publicvoidsetOnLogoutListener(OnLogoutListenerlistner){
mListener=listner;
}
privateHandlermHandler=newHandler(){
publicvoidhandleMessage(Messagemsg){
if(Constant.SUCCESS==msg.what){
mListener.onLogout(true);
}else{
mListener.onLogout(false);
}
};
};
publicvoidlogout(finalStringuser){
newThread(newRunnable(){
@Override
publicvoidrun(){
try{
Socketsocket=newSocket();
socket.connect(newInetSocketAddress("192.168.100.100",8888),4000);
PrintWriterwriter=newPrintWriter(socket.getOutputStream());
writer.println("logout:"+user);
writer.flush();
BufferedReaderreader=newBufferedReader(
newInputStreamReader(socket.getInputStream()));
if("success".equals(reader.readLine())){
PConnection.socket=null;
mHandler.sendEmptyMessage(Constant.SUCCESS);
}else{
mHandler.sendEmptyMessage(Constant.FAILED);
}
}catch(Exceptione){
e.printStackTrace();
}
}
}).start();
}
publicinterfaceOnLogoutListener{
publicvoidonLogout(booleansuccess);
}
}
9.存放登录后的socket,在发送消息和接收消息时使用该socket
publicclassPConnection{
publicstaticSocketsocket;
}
希望本文所述对大家学习有所帮助。