多人聊天室範例
範例三-多人聊天室
連線程式的伺服器有很多時候都必須用到多人連線,以下就為各位示範基礎的多人連線伺服器。
圖1-4為伺服器執行成功的畫面,可以看到下方的訊息欄顯示" Server is start.",也就是服務器啟動,伺服器只有中轉客戶發言及廣播的功能。
圖1-4
圖1-5為使用模擬器開啟客戶端後連入伺服器的展示圖,可以看到下方有兩個方塊第一個方塊示輸入客戶名稱,第二方塊是在輸入要說的話,按鈕是確定送出,用意在於讓伺服端可以中轉客戶端發話的訊息,讓伺服器廣播給其它客戶端。
圖1-5
以下為客戶端與伺服端的程式碼
多人聊天程式-客戶端
專案下載:ClientSocketDemo3.rar
package ccc.ClientSocketDemo3; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.Socket; import ccc.ClientSocketDemo3.R; // public class ClientSocketDemo3 extends Activity { public static Handler mHandler = new Handler(); TextView TextView01; // 用來顯示文字訊息 EditText EditText01; // 文字方塊 EditText EditText02; // 文字方塊 String tmp; // 暫存文字訊息 Socket clientSocket; // 客戶端socket @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 從資源檔裡取得位址後強制轉型成文字方塊 TextView01 = (TextView) findViewById(R.id.TextView01); EditText01=(EditText) findViewById(R.id.EditText01); EditText02=(EditText) findViewById(R.id.EditText02); // 以新的執行緒來讀取資料 Thread t = new Thread(readData); // 啟動執行緒 t.start(); // 從資源檔裡取得位址後強制轉型成按鈕 Button button1=(Button) findViewById(R.id.Button01); // 設定按鈕的事件 button1.setOnClickListener(new Button.OnClickListener() { // 當按下按鈕的時候觸發以下的方法 public void onClick(View v) { // 如果已連接則 if(clientSocket.isConnected()){ BufferedWriter bw; try { // 取得網路輸出串流 bw = new BufferedWriter( new OutputStreamWriter(clientSocket.getOutputStream())); // 寫入訊息 bw.write(EditText01.getText()+":"+EditText02.getText()+"\n"); // 立即發送 bw.flush(); } catch (IOException e) { } // 將文字方塊清空 EditText02.setText(""); } } }); } // 顯示更新訊息 private Runnable updateText = new Runnable() { public void run() { // 加入新訊息並換行 TextView01.append(tmp + "\n"); } }; // 取得網路資料 private Runnable readData = new Runnable() { public void run() { // server端的IP InetAddress serverIp; try { // 以內定(本機電腦端)IP為Server端 serverIp = InetAddress.getByName("10.0.2.2"); int serverPort = 5050; clientSocket = new Socket(serverIp, serverPort); // 取得網路輸入串流 BufferedReader br = new BufferedReader(new InputStreamReader( clientSocket.getInputStream())); // 當連線後 while (clientSocket.isConnected()) { // 取得網路訊息 tmp = br.readLine(); // 如果不是空訊息則 if(tmp!=null) // 顯示新的訊息 mHandler.post(updateText); } } catch (IOException e) { } } }; }
多人聊天程式-伺服端
SocketServerDemo3.rar
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; public class SocketServerDemo3 { private static int serverport = 5050; private static ServerSocket serverSocket; // 用串列來儲存每個client private static ArrayList<Socket> players=new ArrayList<Socket>(); // 程式進入點 public static void main(String[] args) { try { serverSocket = new ServerSocket(serverport); System.out.println("Server is start."); // 當Server運作中時 while (!serverSocket.isClosed()) { // 顯示等待客戶端連接 System.out.println("Wait new clinet connect"); // 呼叫等待接受客戶端連接 waitNewPlayer(); } } catch (IOException e) { System.out.println("Server Socket ERROR"); } } // 等待接受客戶端連接 public static void waitNewPlayer() { try { Socket socket = serverSocket.accept(); // 呼叫創造新的使用者 createNewPlayer(socket); } catch (IOException e) { } } // 創造新的使用者 public static void createNewPlayer(final Socket socket) { // 以新的執行緒來執行 Thread t = new Thread(new Runnable() { @Override public void run() { try { // 增加新的使用者 players.add(socket); // 取得網路串流 BufferedReader br = new BufferedReader( new InputStreamReader(socket.getInputStream())); // 當Socket已連接時連續執行 while (socket.isConnected()) { // 取得網路串流的訊息 String msg= br.readLine(); // 輸出訊息 System.out.println(msg); // 廣播訊息給其它的客戶端 castMsg(msg); } } catch (IOException e) { } // 移除客戶端 players.remove(socket); } }); // 啟動執行緒 t.start(); } // 廣播訊息給其它的客戶端 public static void castMsg(String Msg){ // 創造socket陣列 Socket[] ps=new Socket[players.size()]; // 將players轉換成陣列存入ps players.toArray(ps); // 走訪ps中的每一個元素 for (Socket socket :ps ) { try { // 創造網路輸出串流 BufferedWriter bw; bw = new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())); // 寫入訊息到串流 bw.write(Msg+"\n"); // 立即發送 bw.flush(); } catch (IOException e) { } } } }
Activity介面程式碼
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <LinearLayout android:id="@+id/FrameLayout01" android:layout_height="wrap_content" android:layout_width="fill_parent"> <EditText android:id="@+id/EditText01" android:layout_height="wrap_content" android:text="player01" android:layout_width="wrap_content" android:layout_weight="1"></EditText> <EditText android:id="@+id/EditText02" android:layout_height="wrap_content" android:text="msg" android:layout_width="wrap_content" android:layout_weight="10"></EditText> <Button android:id="@+id/Button01" android:layout_height="wrap_content" android:text="say" android:layout_gravity="right" android:layout_width="wrap_content" android:layout_weight="1"></Button> </LinearLayout> <TextView android:id="@+id/TextView01" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="" /> </LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ccc.ClientSocketDemo3" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ClientSocketDemo1" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="4" /> <!-- 這是註解 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 由於需使用到網路的功能,所以必須加上面這行來取得權限--> </manifest>
程式影片解說
page revision: 44, last edited: 26 May 2011 01:32
感謝分享~!!
請問個程式有辦法應玉在手機上嗎?還是說只能跑模擬器?
請問這個程式有辦法應用在手機上嗎?還是只能用跑模擬器?
Post preview:
Close preview