Android 台灣中文網

打印 上一主題 下一主題

[資料] 以C#編寫的Socket服務器的Android手機聊天室Demo

[複製連結] 查看: 4985|回覆: 10|好評: 1
跳轉到指定樓層
樓主
暗桌之光 | 收聽TA | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
發表於 2011-7-8 15:26

馬上加入Android 台灣中文網,立即免費下載應用遊戲。

您需要 登錄 才可以下載或查看,沒有帳號?註冊

x
  內容摘要
   1.程序架構
   2.通信協議
   3.服務器源代碼
   4.客戶端源代碼
   5.運行效果

一、程序架構
在開發一個聊天室程序時,我們可以使用Socket、Remoting、WCF這些具有雙向通信的協議或框架。而現在,我正要實現一個C#語言作為服務器端、Android作為客戶端的聊天室。由於服務器端和客戶端不是同一語言(C#和java),所有我選擇了Socket作為通信協議。 圖1.1所示,我們可以看出:android手機客戶端A向服務器端發送消息,服務器端收到消息後,又把消息推送到android手機客戶端B。


                               
登錄/註冊後可看大圖

圖1.1

  二、通信協議
我們知道,在C#語言中使用Socket技術需要「四部曲」,即「Bind」,「Listen」,「Accept」,「Receive」。然而Socket編程不像WCF那樣面向對象。而且對應每個請求都用同一種方式處理。作為習慣面向對像編程的我來說,編寫一個傳統的Socket程序很不爽。絞盡腦汁,我們將數據傳輸的格式改為json(JavaScript Object Notation 是一種輕量級的數據交換格式),面對對象的問題就解決了。  假設程序的服務契約有兩個方法:「登陸」和「發送消息」。調用登陸的方法,就傳送方法名(Method Name)為「Logon」的json數據;調用發送消息的方法,就傳送方法名為「Send」的json數據。返回的數據中也使用json格式,這樣在android客戶端中也能知道是哪個方法的返回值了。

  三、服務器源代碼
首先需要編寫一個處理客戶端消息的接口:IResponseManager。
  1.     public interface IResponseManager
  2.     {
  3.         void Write(Socket sender, IList<Socket> cliens, IDictionary<string, object> param);
  4.     }
複製代碼
其次,我們知道,換了是WCF編程的話,就需要在服務契約中寫兩個方法:「登陸」和「發送消息」。由於這裡是Socket編程,我們實現之前寫的IResponseManager接口,一個實現作為「登陸」的方法,另一個實現作為「發送消息」的方法。
  1. public class LogonResponseManager : IResponseManager
  2.     {
  3.         public void Write(System.Net.Sockets.Socket sender, IList<System.Net.Sockets.Socket> cliens, IDictionary<string, object> param)
  4.         {
  5.             Console.WriteLine("客戶端({0})登陸", sender.Handle);
  6.             var response = new SocketResponse
  7.             {
  8.                 Method = "Logon",
  9.                 DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  10.                 Result = new { UserName = param["UserName"].ToString() }
  11.             };

  12.             JavaScriptSerializer jss = new JavaScriptSerializer();
  13.             string context = jss.Serialize(response);
  14.             Console.WriteLine("登陸發送的數據為:{0}", context);
  15.             sender.Send(Encoding.UTF8.GetBytes(context + "\n"));
  16.         }
  17.     }
複製代碼
  1. public class SendResponseManager : IResponseManager
  2.     {
  3.         public void Write(System.Net.Sockets.Socket sender, IList<System.Net.Sockets.Socket> cliens, IDictionary<string, object> param)
  4.         {
  5.             Console.WriteLine("客戶端({0})發送消息", sender.Handle);
  6.             var msgList = param["Message"] as IEnumerable<object>;
  7.             if (msgList == null)
  8.             {
  9.                 return;
  10.             }

  11.             var response = new SocketResponse
  12.             {
  13.                 Method = "Send",
  14.                 DateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
  15.                 Result = new
  16.                 {
  17.                     UserName = param["UserName"].ToString(),
  18.                     Message = msgList.Select(s => s.ToString()).ToArray()
  19.                 }
  20.             };

  21.             JavaScriptSerializer jss = new JavaScriptSerializer();
  22.             string context = jss.Serialize(response);
  23.             Console.WriteLine("消息發送的數據為:{0}", context);

  24.             Parallel.ForEach(cliens, (item) =>
  25.             {
  26.                 try
  27.                 {
  28.                     item.Send(Encoding.UTF8.GetBytes(context + "\n"));
  29.                 }
  30.                 catch { };
  31.             });
  32.         }
  33.     }
複製代碼
最後在Socket程序中使用反射加「策略模式」調用這兩個接口實現類。
  1.             var typeName = "SocketServer." + request.Method + "ResponseManager, SocketServer";
  2.             Console.WriteLine("反射類名為:" + typeName);

  3.             Type type = Type.GetType(typeName);
  4.             if (type == null)
  5.             {
  6.                 return;
  7.             }

  8.             var manager = Activator.CreateInstance(type) as IResponseManager;
  9.             manager.Write(sender, this.socketClientSesson.Select(s => s.Key).ToList(),
  10.                 request.Param as IDictionary<string, object>);
複製代碼
完整的Socket服務器代碼如下:
複製代碼
最後,json數據傳輸的實體對像為:
  1.    [Serializable]
  2.     public class SocketRequest
  3.     {
  4.         public string Method { get; set; }

  5.         public string DateTime { get; set; }

  6.         public object Param { get; set; }
  7.     }
複製代碼
  1.     [Serializable]
  2.     public class SocketResponse
  3.     {
  4.         public string Method { get; set; }

  5.         public string DateTime { get; set; }

  6.         public object Result { get; set; }
  7.     }
複製代碼
運行效果
「用Android 就來APK.TW」,快來加入粉絲吧!
Android 台灣中文網(APK.TW)
熱門小遊戲推薦

評分

參與人數 2幫助 +2 收起 理由
yoyovivi + 1 很給力!
idvtw + 1

查看全部評分

收藏收藏4 分享分享 分享專題
用Android 就來Android 台灣中文網(https://apk.tw)
沙發
sonar | 收聽TA | 只看該作者
發表於 2012-1-2 18:11
請問...
如果想要透過socket來對傳資料?(如mp3,4mp等)
也是透過server 跟client的方式嗎?
可否提供給小弟一些方向。
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

板凳
sonar | 收聽TA | 只看該作者
發表於 2012-1-2 18:17
此外,在請教一下。
程式中 server "C#"的部份,在Eclipse中,Debug Configurations要選擇那個application來Debug?
請指教。
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

地板
tn708516 | 收聽TA | 只看該作者
發表於 2012-8-8 13:52
感謝大大分享
剛好最近在研究這部分的程式碼
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

5
yaxin | 收聽TA | 只看該作者
發表於 2012-9-12 13:39
怎么下载看看呢。
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

6
wwxiaofen | 收聽TA | 只看該作者
發表於 2012-9-14 08:46
谢楼主分享!下载来看看先~~
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

7
cmdunlop | 收聽TA | 只看該作者
發表於 2012-9-17 10:59
sonar 發表於 2012-1-2 18:11
請問...
如果想要透過socket來對傳資料?(如mp3,4mp等)
也是透過server 跟client的方式嗎?

沒錯,使用Byte()來傳送,通常會轉成Stream:這是C#
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

8
cmdunlop | 收聽TA | 只看該作者
發表於 2012-9-17 11:00
sonar 發表於 2012-1-2 18:17
此外,在請教一下。
程式中 server "C#"的部份,在Eclipse中,Debug Configurations要選擇那個application ...

C#是使用visual studio編譯的
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

9
qw0323wq | 收聽TA | 只看該作者
發表於 2012-9-29 22:39
剛好想了解有關於這方面的資訊
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

10
shamslud | 收聽TA | 只看該作者
發表於 2012-10-31 11:06
要怎麼下載呀~~沒有連結說。
用Android 就來Android 台灣中文網(https://apk.tw)
回覆 支持 反對

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 註冊

本版積分規則