http://www.kankanews.com/ICkengine/archives/29985.shtml


摘要:
程序开源,共同学习。最近在学Android,做了一个由Socket实现的基于TCP协议的聊天工具,用一个服务端支持多个客户端之间的交流 通信。虽然本人之前做过蓝牙控制小车的软件,但这次做起来也花了不少时间。没办法,谁叫本人还是只菜鸟,所以下面有哪些说得不当的地方,还请各位多多包涵哦!!

      如果某位朋友也打算做这个Socket聊天工具,本人有个小小的建议,你可以不必太着急些代码,先想清楚自己最终要做到怎样效果,然后把自己的思路都写下来,有一个基本的实现方法。在写代码时就按照自己的思路一步一步地写下去,这样可以很好地避免写代码时由于思路不清左删右改。

以下是本人程序的设计思路

    客户端设计思路:

  一 用户登录界面

1 用一个EditText作为用户名输入口,用一个按键确定。

2 注册一个广播接收器,专门接收由后来的聊天界面发过来的消息广播(包括发信人,收信人,消息体)。

3 创建一个客户端连接服务端的方法(要在线程中启动该方法),连接成功并获取输入输出流以后,再在里面启动一个输入流管理线程(接受并处理由服务端发送过来的消息)。并通过intent启动下一个好友列表界面(同时把自身用户名发给下一界面)。

4 对于输入流管理线程,要先判断接收到的是好友名单还是聊天消息发送两种广播,(服务端发送两种信息时可以加个标签以便线程区分)。然后分发出两种广播,一种广播后面的好友列表界面接受的在线好友名单,另一种广播出聊天界面接收的聊天信息。

5 在菜单下做一个退出Activity按键,方便用户退出程序。

6 当一切准备好以后,用户在输入用户名并点击确定,就可以实现以上操作,同时进入了好友列表界面(前提是能正确连接上服务端)。

               

  二 好友列表界面

1 注册一个广播接收器,专门接收由登录界面的输入流管理线程发送过来的好友名单广播

2 用listView逐个显示好友名单。

3 获取用户登录界面发过来的自身用户名。

4 给listView绑定一个监听器,当用户点击listView上的某一好友时,通过intent启动下一个聊天界面,并把所点击到的好友用户名以及自身用户名发给下一个界面。

               

 

  三 聊天界面

1 获取好友列表界面发送过来的聊天好友用户名以及自身用户名,并在Title上显示。

2 用一个EditText作为聊天消息输入口,用一个按键确定输出。

3 当用户点击确定以后,发送一个消息广播(包含发信人,收信人,消息体),让用户登录界面的消息广播接收器接收。

4 注册一个广播接收器接受用户登录界面的输入流管理线程发送过来的消息。

                   

    服务端设计思路:

  消息处理界面(只有一个界面)

1 创建一个监听连接请求方法 (监听客户端发送连接请求,需要在线程中启动)。

  A  当用户发送连接请求时,生成socket对象。由该socket对象生成输出流和输入流,从输入流中提取出客户端发送过来的用户名,把用户名放到sickName数组上,把输出流放在ArrayOut数组中。

  B  发送新客户端XXX连接成功广播。

  C  预先用sickName数组和ArrayOut数组创建发送好友列表方法(给各已连接客户端发送好友名单),在这里调用方法。

  D  新生成并启动输入流管理线程(接受并处理客户端发送过来的消息,由于有一个新用户生成,就新生一个输入流管理线程,所以客户端发送的消息不会混乱)。

2 创建发送好友列表方法。

3 注册两个广播接收器,一个接收新客户端XXX连接成功广播;另一个接收输入流管理线程发送过来的聊天消息,识别出目标对象,并向目标对象分别发送消息。

4 在onResume方法中启动监听线程。

5 在菜单下做一个退出Activity按键和刷新按钮(再次发送已连接用户名单给各客户端)。

 

    可完善地方:

 可考虑好友退出时显示离线。

 非正在聊天好友发送信息时提醒。

 只要登录了,未接信息可以一直保存,当进入聊天界面时可以再度显示。

 可考虑添加LQ头像与聊天表情。

 。。。。。。

客户端代码:

1 用户登录界面

 

package cn.text2;



import java.io.BufferedWriter;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;







import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;



public class Text2Activity extends Activity {

	

	

	Button buttonSure;

	Button buttonDump;

	EditText editTextName;

	PrintWriter output ;

	Text2Helper text2helper;

	int k = 0;

	

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    	

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        buttonSure = (Button)findViewById(R.id.buttonSure);

        editTextName = (EditText)findViewById(R.id.editTextName);

        

    }

    

    /*****确定按键*******/

    public void buttonsure(View v) {

    	

		 new Thread(){

			public void run(){

				Connect();

				System.out.println("注册Text2ClientActivity的发送信息广播");

			}

		 }.start();

		 System.out.println("注册Text2ClientActivity的发送信息广播");

		 OpenBroadcastReceiver();

		 

	 }

    



    /****注册广播方法*******/

	public void OpenBroadcastReceiver(){

		

		//生成BroadcastReceiver对象

		Text2ClientActivityReceiver Receiver = new Text2ClientActivityReceiver();

		//生成过滤器IntentFilter对象

		IntentFilter filter = new IntentFilter();

		//为过滤器添加识别标签

		filter.addAction("android.intent.action.VOICE_COMMAND");//读取Text2ClientActivity的发送信息广播

		//接收广播状态

		Text2Activity.this.registerReceiver(Receiver, filter);

		System.out.println("注册广播完成!");

		

	}

	

		/********广播接收器类***********///专门读取Text2ClientActivity的发送信息广播

	public class Text2ClientActivityReceiver extends BroadcastReceiver {

		

		@Override

		public void onReceive(Context context, Intent intent) {

			// TODO Auto-generated method stub

			String yourself = intent.getStringExtra("SendYourself");//接收要发送的对象名称以及信息        

			String target = intent.getStringExtra("SendTarget");

			String message = intent.getStringExtra("SendMessage");

			if(k>0){

				 output.println(yourself);  //yourself

				 output.flush();

				 output.println(target);  //target

				 output.flush();

				 output.println(message);  //内容

				 output.flush();

				 System.out.println("接收器接收到Text2ClientActivity的广播,并发送到服务端");

			}



		}

		

	}

	



	

	

	 /*********启动客户端方法***********/

	 public void Connect(){

			

			try {

				 InetAddress addr = InetAddress.getByName("192.168.22.10");//服务端手机网络IP地址,连一下wifi就可以知道

				 System.out.println("客户端发出请求");

				 

				 //客户端向服务端发出连接请求

				 Socket socket = new Socket(addr,6666);

		         System.out.println("连接成功,socket=" + socket);

		         

		         //通过该条socket通道得到输出流

		         output = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

		         System.out.println("输出流获取成功");

		         output.println(editTextName.getEditableText().toString());

		         output.flush();

		         k++;

		         

		         //启动getMessage线程

		         text2helper = new Text2Helper(socket,this);  //生成新的CGetMessage对象即调用一次CGetMessage

		         Thread gt = new Thread(text2helper);

		         gt.start();

		         

		         /**跳转到下一个FriendListActivity**/

		         Intent intentdump =new Intent();

				 intentdump.putExtra("ClientName",editTextName.getText().toString());

				 intentdump.setClass(Text2Activity.this, Text2FriendActivity.class);

				 Text2Activity.this.startActivity(intentdump);

			  } catch (Exception e) {

				 e.printStackTrace();

			  }

			 

	 }

	 

	 

	 /********菜单功能**********/

	 @Override

	 public boolean onCreateOptionsMenu(Menu menu) {

		 

		  menu.add(0,1,1,"退出");

		  menu.add(0,2,2,"连接");

		  return true;

	  

	 }

	 

	 @Override

	 public boolean onMenuItemSelected(int featureId, MenuItem item) {

		 

		  if(item.getItemId() == 1){

			  finish();

		  }

		  

		  if(item.getItemId() == 2){

			  new Thread(){

					

					public void run()

					{

						Connect();

					}

				}.start();

		  }

		  

	  return super.onMenuItemSelected(featureId, item);

	  

	 }

    

    

}

 2 好友列表界面

package cn.text2;



import java.util.ArrayList;

import java.util.HashMap;



import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ListView;

import android.widget.SimpleAdapter;

import android.widget.TextView;

import android.widget.Toast;

import android.widget.AdapterView.OnItemClickListener;



public class Text2FriendActivity extends Activity {



	

	TextView textViewfriendlist;

	ListView listViewfriendlist;

	static Toast tt = null;

	

	int i = 1;

	String Clients[] = {"","","","","","","","","","","","","","","","","","","","","","","","",""};

	String YourName;

	

	SimpleAdapter simpleAdapter;

	ArrayList<HashMap<String, String>> listItem;

	

	 @Override

	protected void onCreate(Bundle savedInstanceState) {

		 

		  super.onCreate(savedInstanceState);

		  setContentView(R.layout.friend);

		  Intent intentdump = getIntent();

		  YourName = intentdump.getStringExtra("ClientName");

		  listViewfriendlist = (ListView)findViewById(R.id.listViewfriendlist);

		  textViewfriendlist = (TextView)findViewById(R.id.textViewfriendlist);

		  

		  /**********listView数据数组与适配器的定义*************/

		  listItem = new ArrayList<HashMap<String,String>>();//定义列表数组 

		  HashMap<String, String> map = new HashMap<String, String>();  

		  map.put("LvMessage","好友:");  

		  listItem.add(map); 

		  simpleAdapter = new SimpleAdapter(this,listItem,

		  R.layout.text2user,new String[] {"LvMessage"},new int[] {R.id.LvTextViewMessage});	//定义适配器

		  listViewfriendlist.setAdapter(simpleAdapter);    

		  listViewfriendlist.setOnItemClickListener(new ListViewListener());

		  

		  OpenBroadcastReceiver();//注册接收UpLoadActivity发送过来的好友名单广播

		  Clients[0]= "Jack";

		  

	}

	

	/*******listView的监听器**********/

	class ListViewListener implements OnItemClickListener{

    	

		@Override

		public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {

			

			// TODO Auto-generated method stub

			setTitle("你点击了第"+arg2+"行");//设置标题栏显示点击的行    (从0开始) 

//			if(arg2>0){

				/**跳转到下一个Text2ClientActivity**/

		         Intent intentdump2 =new Intent();

		         intentdump2.putExtra("Target",Clients[arg2]);//目标联系人

		         intentdump2.putExtra("Yourself", YourName);//自身用户名

		         intentdump2.setClass(Text2FriendActivity.this, Text2TalkActivity.class);

		         Text2FriendActivity.this.startActivity(intentdump2);

//			}

			

		}

		

    }

	



	/****注册广播方法*******/

	public void OpenBroadcastReceiver(){

		

		//生成BroadcastReceiver对象

		FriendListReceiver Receiver = new FriendListReceiver();

		//生成过滤器IntentFilter对象

		IntentFilter filter = new IntentFilter();

		//为过滤器添加识别标签

		filter.addAction("android.intent.action.DIAL");  

		//接收广播状态

		Text2FriendActivity.this.registerReceiver(Receiver, filter);

		System.out.println("注册广播完成!");

		

	}

	

	/********广播接收器类***********///接收UpLoadActivity发送过来的好友名单

	public class FriendListReceiver extends BroadcastReceiver {

		

		@Override

		public void onReceive(Context context, Intent intent) {

			

			// TODO Auto-generated method stub

			String msg = intent.getStringExtra("FriendListmessage");

			//给列表添加数据

			Clients[i] = msg;

			HashMap<String, String> map = new HashMap<String, String>(); 

			map.put("LvMessage",msg);  

			listItem.add(map);  

			listViewfriendlist.setAdapter(simpleAdapter);    

			System.out.println("接收器接收到广播--->"+msg+",并显示在listView上");

			i++;

		}

		



	}

		

	

	

	

	/********菜单功能**********/

	 @Override

	 public boolean onCreateOptionsMenu(Menu menu) {

		 

		  menu.add(0,1,1,"退出");

		  return true;

	  

	 }

	 

	 @Override

	 public boolean onMenuItemSelected(int featureId, MenuItem item) {

		 

		  if(item.getItemId() == 1){

			  finish();

		  }

		  

	  return super.onMenuItemSelected(featureId, item);

	  

	 }

	 

	 

}

 3 聊天界面

package cn.text2;



import java.io.BufferedWriter;

import java.io.DataInputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.Socket;

import java.util.ArrayList;

import java.util.HashMap;



import android.app.Activity;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.os.Message;

import android.os.Vibrator;

import android.text.Editable;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.SimpleAdapter;

import android.widget.TextView;

import android.widget.Toast;



public class Text2TalkActivity extends Activity {

	

	

	 TextView textViewMessage;

	 Button buttonSend;

	 EditText editText;

	 ListView listView;

	 Vibrator vibrator;

	 static Toast tt = null;

	 

	 SimpleAdapter simpleAdapter;

	 ArrayList<HashMap<String, String>> listItem;

	 

	 String Yourself;

	 String Target;

	 

	 @Override

	 protected void onCreate(Bundle savedInstanceState) {

		 

	  super.onCreate(savedInstanceState);

	  setContentView(R.layout.talk);

	  

	  Intent intent2 = getIntent();

	  Yourself = intent2.getStringExtra("Yourself");

	  Target = intent2.getStringExtra("Target");

	  setTitle("I am "+Yourself+"     --->"+Target);

	  

	  textViewMessage = (TextView)findViewById(R.id.textViewMessage);

	  buttonSend = (Button)findViewById(R.id.buttonSend);

	  editText = (EditText)findViewById(R.id.editText);

	  listView = (ListView)findViewById(R.id.listView);

	  tt = Toast.makeText(Text2TalkActivity.this, "有消息", Toast.LENGTH_SHORT);

	  

	  /**********listView数据数组与适配器的定义*************/

	  listItem = new ArrayList<HashMap<String,String>>();//定义列表数组 

	  HashMap<String, String> map = new HashMap<String, String>();  

	  map.put("LvMessage","聊天内容:");  

	  listItem.add(map); 

	  simpleAdapter = new SimpleAdapter(this,listItem,

	  R.layout.text2user,new String[] {"LvMessage"},new int[] {R.id.LvTextViewMessage});	//定义适配器

	  listView.setAdapter(simpleAdapter);

	  

	  Text2TalkBroadcastReceiver();

	  

	 }

	 

		

		/******发送信息按钮监听器********/

		public void buttonsend(View v) {

			

			HashMap<String, String> map = new HashMap<String, String>(); 

			map.put("LvMessage", Yourself +":"+editText.getEditableText());  

			listItem.add(map);  

			listView.setAdapter(simpleAdapter);   

			

			Intent intent = new Intent();

        	intent.setAction(intent.ACTION_VOICE_COMMAND);//给UploadActivity发送广播yourself

        	intent.putExtra("SendYourself",Yourself);

        	intent.putExtra("SendTarget",Target);

        	intent.putExtra("SendMessage",editText.getEditableText().toString());

        	Text2TalkActivity.this.sendBroadcast(intent);

        	

			System.out.println("向服务端发送信息:"+editText.getEditableText());

			

		}

		 

	 /****注册广播方法*******/

	public void Text2TalkBroadcastReceiver(){

		

		//生成BroadcastReceiver对象

		Text2TalkbroadcastReceiver Receiver = new Text2TalkbroadcastReceiver();

		//生成过滤器IntentFilter对象

		IntentFilter filter = new IntentFilter();

		//为过滤器添加识别标签

		filter.addAction("android.intent.action.PICK");  //接收由Text2FriendActivity发送过来的信息

		//接收广播状态

		Text2TalkActivity.this.registerReceiver(Receiver, filter);

		System.out.println("注册广播完成!");

		

	}

	

		/********广播接收器类***********///接收由Text2FriendActivity发送过来的信息

	public class Text2TalkbroadcastReceiver extends BroadcastReceiver {

		

		@Override

		public void onReceive(Context context, Intent intent) {

			

			// TODO Auto-generated method stub

			String msg = intent.getStringExtra("TextMessage");

			//给列表添加数据

			HashMap<String, String> map = new HashMap<String, String>(); 

			map.put("LvMessage", msg);  

			listItem.add(map);  

			listView.setAdapter(simpleAdapter);    

			System.out.println("Text2Talk接收器接收到广播--->"+msg+",并显示在listView上");

			

			vibrator();//震动

			

		}

			

	}

	

	/******震动30ms方法******/

    public void vibrator(){  

    	

    	vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);

    	vibrator.vibrate(30);

    	System.out.println("震动30ms");

    	

    }

	



	/*************菜单*******************/

	 @Override

	 public boolean onCreateOptionsMenu(Menu menu) {

		 

		  menu.add(0,0,0,"清除");

		  menu.add(0,1,1,"退出");

		  return true;

	  

	 }

	 

	 @Override

	 public boolean onMenuItemSelected(int featureId, MenuItem item) {

		 

		  if(item.getItemId() == 0){

			  ArrayList<HashMap<String, String>> listItem1 = new ArrayList<HashMap<String,String>>();/*在数组中存放数据*/ 

			  HashMap<String, String> map = new HashMap<String, String>();  

			  map.put("ItemText","聊天内容:");  

			  listItem1.add(map);  

			  SimpleAdapter simpleAdapter1 = new SimpleAdapter(this,listItem1,

					  R.layout.text2user,new String[] {"ItemText"},new int[] {R.id.LvTextViewMessage});

			  listView.setAdapter(simpleAdapter1);

		  }

		  

		  if(item.getItemId() == 1){

			  finish();

		  }

		  

	  return super.onMenuItemSelected(featureId, item);

	 }





}

 

 

服务端代码:

package cn.Text2Server;



import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.DataInputStream;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.InetAddress;

import java.net.ServerSocket;

import java.net.Socket;

import java.net.SocketAddress;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;



import android.app.Activity;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.SimpleAdapter;

import android.widget.TextView;

import android.widget.Toast;



public class Text2ServerActivity  extends Activity {

	

	

	 TextView textViewHead = null;

	 TextView textViewMessage;

	 Button buttonStart;

	 Button buttonSend;

	 EditText editText;

	 ListView listView;

	 static Toast toast = null;

	 

	 PrintWriter out,o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12,o13,o14,o15,o16,o17,o18,o19,o20;

	 PrintWriter ArrayOut[] = {o1,o2,o3,o4,o5,o6,o7,o8,o9,o10,o11,o12,o13,o14,o15,o16,o17,o18,o19,o20};

	 				//直接写(PrintWriter[]  ArrayOut)不成功

	 int k = 0;  	//记录已连接的客户端数

	 int m = 0;		// 区分显示在服务端的目标对象与body

	 String ReceiveMessage = "客户端:\n";

	 String nickName[] = {"","","","","","","","","","","","","","","","","","","","","","","","",""};

	 String from,to,body;

	 String packet[] = {from,to,body};

	 

	 SimpleAdapter simpleAdapter;

	 ArrayList<HashMap<String, String>> listItem;

	 HashMap<String, String> map;

	 

	 

	 @Override

	 protected void onCreate(Bundle savedInstanceState) {

		 

		  super.onCreate(savedInstanceState);

		  setContentView(R.layout.main);

		  textViewHead = (TextView)findViewById(R.id.textView);

		  textViewMessage = (TextView)findViewById(R.id.textViewMessage);

		  buttonSend = (Button)findViewById(R.id.buttonSend);

		  editText = (EditText)findViewById(R.id.editText);

		  listView = (ListView)findViewById(R.id.listView);

                    toast = Toast.makeText(Text2ServerActivity.this, "连接成功", Toast.LENGTH_SHORT);

		  

		  /**********listView数据数组与适配器的定义*************/

		  listItem = new ArrayList<HashMap<String,String>>();//定义列表数组 

		  map = new HashMap<String, String>();  

		  map.put("LvMessage","聊天内容:");  

		  listItem.add(map); 

		  simpleAdapter = new SimpleAdapter(this,listItem,

		  R.layout.user,new String[] {"LvMessage"},new int[] {R.id.LvTextViewMessage});	//定义适配器

		  listView.setAdapter(simpleAdapter);    

		  

		  

	 }

	 

	 

	 /********发送信息按钮监听器*******/  //这个可以不要

	 public void buttonsend(View v){

		 

		 HashMap<String, String> map = new HashMap<String, String>(); 

		 map.put("LvMessage", "服务端:"+editText.getEditableText());  

		 listItem.add(map);  

		 listView.setAdapter(simpleAdapter);   

		 

		 out.println(editText.getEditableText());//发送出该字符串

		 out.flush();

		 System.out.println("向客户端发送信息:"+editText.getEditableText());

	 }

	 

	 

	 /****注册接收信息广播方法*******/	

	 public void OpenBroadcastReceiver(){

		 

		 //生成BroadcastReceiver对象

		 broadcastReceiver Receiver = new broadcastReceiver();

		 //生成过滤器IntentFilter对象

		 IntentFilter filterMessage = new IntentFilter();

		 //为过滤器添加识别标签

		 filterMessage.addAction("android.intent.action.EDIT");

		 //接收广播状态

		 Text2ServerActivity.this.registerReceiver(Receiver, filterMessage);

		 System.out.println("注册广播完成!");

		 

	 }

	 

	 

	 /********信息广播接收器类***********/ 

	 public class broadcastReceiver extends BroadcastReceiver {

			

		 @Override

		 public void onReceive(Context context, Intent intent) {

			 // TODO Auto-generated method stub

			 

			 //给列表添加数据

			 String msg = intent.getStringExtra("message");

			 packet[m] = msg;

			 m++;

			 if(msg.equals("监听中")||msg.equals("已连接")){

				 textViewHead.setText("服务端:     状态:"+msg);   

				 System.out.println("接收器已接收到连接状态msg并显示在TextView上");

				 m = 0;

			 }

			 if(m>=3){

				 m = 0;

				 String ReceiveMessage = "From  客户端-"+packet[0]+ "To   客户端-"+packet[1] + " :"+packet[2];

				 HashMap<String, String> map = new HashMap<String, String>(); 

				 map.put("LvMessage", ReceiveMessage);  

				 listItem.add(map);  

				 listView.setAdapter(simpleAdapter);    

				 System.out.println("接收器已接收到消息并显示在ListView上");

					 

				 for(int i=0;i<k;i++){  	//让目标对象与好友名单列表逐个对比

						 if(nickName[i].equals(packet[1])){

							 SendMessage(ArrayOut[i],packet[0]+":"+packet[2]);

							 break;

						 }

					 }

						 

				 }

			 

		 }



	 }

	 

	 

	 /********发送信息方法**************/

	 public void SendMessage(PrintWriter target,String msg){

		 

		 target.println(msg);

		 target.flush();

		 

	 }

	 

	 

	 /****注册接收已连接用户名称广播方法*******/

	 public void ConnectedClientReceiver(){

		 

		 //生成BroadcastReceiver对象

		 ConnectedClientbroadcastReceiver Receiver2 = new ConnectedClientbroadcastReceiver();

		 //生成过滤器IntentFilter对象

		 IntentFilter filterfriends = new IntentFilter();

		 //为过滤器添加识别标签

		 filterfriends.addAction("android.intent.action.INSERT");

		 //接收广播状态

		 Text2ServerActivity.this.registerReceiver(Receiver2, filterfriends);

		 System.out.println("注册广播完成!");

		 

	 }

	 

	 /********接收已连接用户名称广播接收器类***********/

	 public class ConnectedClientbroadcastReceiver extends BroadcastReceiver {

			

		 @Override

		 public void onReceive(Context context, Intent intent) {

			 // TODO Auto-generated method stub

			 

			 String msg = intent.getStringExtra("nickname");

			 textViewMessage.setText(textViewMessage.getText()+msg+"\n");

			 System.out.println("向各客户端发送好友列表");

			 

		 }



	 }

	 

	 

	 

	 /*****onResume方法:启动监听线程*******/

	 @Override

	protected void onResume() {

		 

		// TODO Auto-generated method stub

		super.onResume();

		new Thread(){

			

			public void run()

			{

				StartListener();

			}

			

		}.start();

		System.out.println("注册广播");

		OpenBroadcastReceiver();

		ConnectedClientReceiver();

		

	}

	 

	 

	 /**********向各客户端发送好友列表方法**************/

	 public void SendFriendList(){

		 

		//发送已连接用户名单给个客户端线程

		 for(int m=0;m<k;m++){ //m代表客户端序号

			 

				if(m==k-1){  //k-1代表新连接的客户端

					ArrayOut[m].println("&");//&,让客户端识别到是好友名单即将发送的标志

					ArrayOut[m].flush();

					for(int n=0;n<=k-1;n++){  //n代表是好友名单序号

						ArrayOut[m].println(nickName[n]);     

						ArrayOut[m].flush();

					}

					ArrayOut[m].println("#");//#,让客户端识别到是好友名单发送完毕的标志

					ArrayOut[m].flush();

						

				}

				else{

					ArrayOut[m].println("&");

					ArrayOut[m].flush();

					ArrayOut[m].println(nickName[k-1]);     

					ArrayOut[m].flush();

					ArrayOut[m].println("#");

					ArrayOut[m].flush();

				}

				

			}



	 }

	 

	 

	/*********监听连接请求方法 ********/

	 public void StartListener(){

		 

		 while(true){

			 

		  try {

				//服务端监听6666端口

			   ServerSocket s = new ServerSocket(6666);

			   System.out.println("服务器端------监听中......");

			   Intent intent = new Intent();

			   intent.setAction(intent.ACTION_EDIT);

			   intent.putExtra("message","监听中");

			   Text2ServerActivity.this.sendBroadcast(intent);

			   System.out.println("监听中");	

			

			   Socket socket = s.accept();

			   

			   System.out.println("通道连接成功\n"+"socket:" + socket);

			   

			   //获取刚连接客户端的输出流并放在数组上

			   PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

			   ArrayOut[k] = out;

			   

			   //获取刚连接客户端的名称并放在数组上

			   BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));

			   String name =br.readLine();	

			   nickName[k] = name;

			            

			   //在服务端显示已连接好友

			   Intent intent1 = new Intent();

			   intent1.setAction(intent.ACTION_INSERT);  //向自身发送传输广播

			   intent1.putExtra("nickname",name);

			   Text2ServerActivity.this.sendBroadcast(intent1);

			   System.out.println("好友"+name+"已连接上服务端");	

			   

			   //在服务端显示连接成功

			   Intent intent2 = new Intent();

			   Text2ServerActivity.this.toast.show();

			   intent2.setAction(intent.ACTION_EDIT);  //向自身发送传输广播

			   intent2.putExtra("message","已连接");	

			   Text2ServerActivity.this.sendBroadcast(intent2);

			   System.out.println("发送完成客户端连接请求广播");	

			   k++;

			   //发送已连接用户名单给各个客户端

			   SendFriendList();

		   

			   

			   //启动GetMessage线程

			   GetMessage gm = new GetMessage(socket,this);  //生成新的runnable实现类对象

			   Thread gt = new Thread(gm);  //生成新的线程

			   gt.start(); //启动线程

			   System.out.println("启动getMesage线程");

		  } catch (IOException e1) {

		   e1.printStackTrace();

		  }

		 }

	 }

	 

	 

	 /************菜单*************/

	 @Override

	 public boolean onCreateOptionsMenu(Menu menu) {

		 

	  menu.add(0,0,0,"清除");

	  menu.add(0,1,1,"退出");

	  menu.add(0,2,2,"刷新");//再次发送已连接用户名单给各个客户端

	  return true;

	  

	 }

	 

	 @Override

	 public boolean onMenuItemSelected(int featureId, MenuItem item) {

		 

		  if(item.getItemId() == 0){

			  ArrayList<HashMap<String, String>> listItem1 = new ArrayList<HashMap<String,String>>();/*在数组中存放数据*/ 

			  HashMap<String, String> map = new HashMap<String, String>();  

			  map.put("ItemText", "聊天内容:");  

			  listItem.add(map);  

			  SimpleAdapter simpleAdapter1 = new SimpleAdapter(this,listItem1,

					  R.layout.user,new String[] {"ItemText"},new int[] {R.id.LvTextViewMessage}  );

			  listView.setAdapter(simpleAdapter1);

		        

		  }

		  

		  if(item.getItemId() == 1){

			  finish();

		  }

		  

		  if(item.getItemId() == 2){

			  

			  for(int m=0;m<k;m++){ //m代表客户端序号

					if(m==k-1){  //k-1代表新连接的客户端

						ArrayOut[m].println("&");//&,让客户端识别到是好友名单即将发送的标志

						ArrayOut[m].flush();

						for(int n=0;n<=k-1;n++){  //n代表是好友名单序号

							ArrayOut[m].println(nickName[n]);     

							ArrayOut[m].flush();

						}

						ArrayOut[m].println("#");//#,让客户端识别到是好友名单发送完毕的标志

						ArrayOut[m].flush();

							

					}

					else{

						ArrayOut[m].println("&");

						ArrayOut[m].flush();

						ArrayOut[m].println(nickName[k-1]);     

						ArrayOut[m].flush();

						ArrayOut[m].println("#");

						ArrayOut[m].flush();

					}

				}

			  

		  }

		  

	  return super.onMenuItemSelected(featureId, item);

	  

	 }

	 

	 

}

好了,就写这么多,希望对各位想做Socket聊天工具的朋友有所帮助!!


声明:OSCHINA 博客文章版权属于作者,受法律保护。未经作者同意不得转载。


Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐