Android Socket 聊天工具(一個服務端實現多個客戶端間通訊)

      若是某位朋友也打算作這個Socket聊天工具,本人有個小小的建議,你能夠沒必要太着急些代碼,先想清楚本身最終要作到怎樣效果,而後把本身的思路都寫下來,有一個基本的實現方法。在寫代碼時就按照本身的思路一步一步地寫下去,這樣能夠很好地避免寫代碼時因爲思路不清左刪右改 java

如下是本人程序的設計思路 android

    客戶端設計思路: 數組

  一 用戶登陸界面 服務器

用一個EditText做爲用戶名輸入口,用一個按鍵肯定。 網絡

註冊一個廣播接收器,專門接收由後來的聊天界面發過來的消息廣播(包括髮信人,收信人,消息體)。 併發

建立一個客戶端鏈接服務端的方法(要在線程中啓動該方法),鏈接成功並獲取輸入輸出流之後,再在裏面啓動一個輸入流管理線程(接受並處理由服務端發送過來的消息)。並經過intent啓動下一個好友列表界面(同時把自身用戶名發給下一界面)。 app

對於輸入流管理線程,要先判斷接收到的是好友名單仍是聊天消息發送兩種廣播,(服務端發送兩種信息時能夠加個標籤以便線程區分)。而後分發出兩種廣播,一種廣播後面的好友列表界面接受的在線好友名單,另外一種廣播出聊天界面接收的聊天信息。 socket

菜單下作一個退出Activity按鍵,方便用戶退出程序。 ide

當一切準備好之後,用戶在輸入用戶名並點擊肯定,就能夠實現以上操做,同時進入了好友列表界面(前提是能正確鏈接上服務端)。 工具

               

  二 好友列表界面

註冊一個廣播接收器,專門接收由登陸界面的輸入流管理線程發送過來的好友名單廣播

listView逐個顯示好友名單。

獲取用戶登陸界面發過來的自身用戶名。

listView綁定一個監聽器,當用戶點擊listView上的某一好友時,經過intent啓動下一個聊天界面,並把所點擊到的好友用戶名以及自身用戶名發給下一個界面。

               

 

  三 聊天界面

獲取好友列表界面發送過來的聊天好友用戶名以及自身用戶名,並在Title上顯示。

用一個EditText做爲聊天消息輸入口,用一個按鍵肯定輸出。

當用戶點擊肯定之後,發送一個消息廣播(包含發信人,收信人,消息體),讓用戶登陸界面的消息廣播接收器接收。

註冊一個廣播接收器接受用戶登陸界面的輸入流管理線程發送過來的消息。

                   

 

    服務端設計思路:

  消息處理界面(只有一個界面)

建立一個監聽鏈接請求方法 (監聽客戶端發送鏈接請求,須要在線程中啓動)。

  A  當用戶發送鏈接請求時,生成socket對象。由該socket對象生成輸出流和輸入流,從輸入流中提取出客戶端發送過來的用戶名,把用戶名放到sickName數組上,把輸出流放在ArrayOut數組中。

  B  發送新客戶端XXX鏈接成功廣播。

  C  預先用sickName數組和ArrayOut數組建立發送好友列表方法(給各已鏈接客戶端發送好友名單),在這裏調用方法。

  D  新生成並啓動輸入流管理線程(接受並處理客戶端發送過來的消息,因爲有一個新用戶生成,就新生一個輸入流管理線程,因此客戶端發送的消息不會混亂)。

建立發送好友列表方法

註冊兩個廣播接收器,一個接收新客戶端XXX鏈接成功廣播;另外一個接收輸入流管理線程發送過來的聊天消息,識別出目標對象,並向目標對象分別發送消息。

onResume方法中啓動監聽線程。

菜單下作一個退出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聊天工具的朋友有所幫助!!
相關文章
相關標籤/搜索