以C#编写的Socket服务器的Android手机聊天室Demo
?
?? 內容摘要
?? 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。
?
????public?interface?IResponseManager????{
????????void?Write(Socket?sender,?IList<Socket>?cliens,?IDictionary<string,?object>?param);
????}
?
?
其次,我們知道,換了是WCF編程的話,就需要在服務契約中寫兩個方法:“登陸”和“發送消息”。由于這里是Socket編程,我們實現之前寫的IResponseManager接口,一個實現作為“登陸”的方法,另一個實現作為“發送消息”的方法。
?
public?class?LogonResponseManager?:?IResponseManager????{
????????public?void?Write(System.Net.Sockets.Socket?sender,?IList<System.Net.Sockets.Socket>?cliens,?IDictionary<string,?object>?param)
????????{
????????????Console.WriteLine("客戶端({0})登陸",?sender.Handle);
????????????var?response?=?new?SocketResponse
????????????{
????????????????Method?=?"Logon",
????????????????DateTime?=?DateTime.Now.ToString("yyyy-MM-dd?HH:mm:ss"),
????????????????Result?=?new?{?UserName?=?param["UserName"].ToString()?}
????????????};
????????????JavaScriptSerializer?jss?=?new?JavaScriptSerializer();
????????????string?context?=?jss.Serialize(response);
????????????Console.WriteLine("登陸發送的數據為:{0}",?context);
????????????sender.Send(Encoding.UTF8.GetBytes(context?+?"\n"));
????????}
????}
?
?
public?class?SendResponseManager?:?IResponseManager????{
????????public?void?Write(System.Net.Sockets.Socket?sender,?IList<System.Net.Sockets.Socket>?cliens,?IDictionary<string,?object>?param)
????????{
????????????Console.WriteLine("客戶端({0})發送消息",?sender.Handle);
????????????var?msgList?=?param["Message"]?as?IEnumerable<object>;
????????????if?(msgList?==?null)
????????????{
????????????????return;
????????????}
????????????var?response?=?new?SocketResponse
????????????{
????????????????Method?=?"Send",
????????????????DateTime?=?DateTime.Now.ToString("yyyy-MM-dd?HH:mm:ss"),
????????????????Result?=?new
????????????????{?
????????????????????UserName?=?param["UserName"].ToString(),
????????????????????Message?=?msgList.Select(s?=>?s.ToString()).ToArray()?
????????????????}
????????????};
????????????JavaScriptSerializer?jss?=?new?JavaScriptSerializer();
????????????string?context?=?jss.Serialize(response);
????????????Console.WriteLine("消息發送的數據為:{0}",?context);
????????????Parallel.ForEach(cliens,?(item)?=>
????????????{
????????????????try
????????????????{
????????????????????item.Send(Encoding.UTF8.GetBytes(context?+?"\n"));
????????????????}
????????????????catch?{?};
????????????});
????????}
????}
?
最后在Socket程序中使用反射加“策略模式”調用這兩個接口實現類。
?
????????????var?typeName?=?"SocketServer."?+?request.Method?+?"ResponseManager,?SocketServer";????????????Console.WriteLine("反射類名為:"?+?typeName);
????????????Type?type?=?Type.GetType(typeName);
????????????if?(type?==?null)
????????????{
????????????????return;
????????????}
????????????var?manager?=?Activator.CreateInstance(type)?as?IResponseManager;
????????????manager.Write(sender,?this.socketClientSesson.Select(s?=>?s.Key).ToList(),
????????????????request.Param?as?IDictionary<string,?object>);
?
完整的Socket服務器代碼如下:
?
public?class?SocketHost????{
????????private?IDictionary<Socket,?byte[]>?socketClientSesson?=?new?Dictionary<Socket,?byte[]>();
????????public?int?Port?{?get;?set;?}
????????public?void?Start()
????????{
????????????var?socketThread?=?new?Thread(()?=>
????????????{
????????????????Socket?socket?=?new?Socket(AddressFamily.InterNetwork,?SocketType.Stream,?ProtocolType.Tcp);
????????????????IPEndPoint?iep?=?new?IPEndPoint(IPAddress.Any,?this.Port);
????????????????//綁定到通道上
????????????????socket.Bind(iep);
????????????????//偵聽
????????????????socket.Listen(6);
????????????????//通過異步來處理
????????????????socket.BeginAccept(new?AsyncCallback(Accept),?socket);
????????????});
????????????socketThread.Start();
????????????Console.WriteLine("服務器已啟動");
????????}
????????private?void?Accept(IAsyncResult?ia)
????????{
????????????Socket?socket?=?ia.AsyncState?as?Socket;
????????????var?client?=?socket.EndAccept(ia);
????????????socket.BeginAccept(new?AsyncCallback(Accept),?socket);
????????????byte[]?buf?=?new?byte[1024];
????????????this.socketClientSesson.Add(client,?buf);
????????????try
????????????{
????????????????client.BeginReceive(buf,?0,?buf.Length,?SocketFlags.None,?new?AsyncCallback(Receive),?client);
????????????????string?sessionId?=?client.Handle.ToString();
????????????????Console.WriteLine("客戶端({0})已連接",?sessionId);
????????????}
????????????catch?(Exception?ex)
????????????{
????????????????Console.WriteLine("監聽請求時出錯:\r\n"?+?ex.ToString());
????????????}
????????}
????????private?void?Receive(IAsyncResult?ia)
????????{
????????????var?client?=?ia.AsyncState?as?Socket;
????????????if?(client?==?null?||?!this.socketClientSesson.ContainsKey(client))
????????????{
????????????????return;
????????????}
????????????int?count?=?client.EndReceive(ia);
????????????byte[]?buf?=?this.socketClientSesson[client];
????????????if?(count?>?0)
????????????{
????????????????try
????????????????{
????????????????????client.BeginReceive(buf,?0,?buf.Length,?SocketFlags.None,?new?AsyncCallback(Receive),?client);
????????????????????string?context?=?Encoding.UTF8.GetString(buf,?0,?count);
????????????????????Console.WriteLine("接收的數據為:",?context);
????????????????????this.Response(client,?context);
????????????????}
????????????????catch?(Exception?ex)
????????????????{
????????????????????Console.WriteLine("接收的數據出錯:\r\n{0}",?ex.ToString());
????????????????}
????????????}
????????????else
????????????{
????????????????try
????????????????{
????????????????????string?sessionId?=?client.Handle.ToString();
????????????????????client.Disconnect(true);
????????????????????this.socketClientSesson.Remove(client);
????????????????????Console.WriteLine("客戶端({0})已斷開",?sessionId);
????????????????}
????????????????catch?(Exception?ex)
????????????????{
????????????????????Console.WriteLine("客戶端已斷開出錯"?+?ex.ToString());
????????????????}
????????????}
????????}
????????private?void?Response(Socket?sender,?string?context)
????????{
????????????SocketRequest?request?=?null;
????????????JavaScriptSerializer?jss?=?new?JavaScriptSerializer();
????????????request?=?jss.Deserialize(context,?typeof(SocketRequest))?as?SocketRequest;
????????????if?(request?==?null)
????????????{
????????????????return;
????????????}
????????????var?typeName?=?"SocketServer."?+?request.Method?+?"ResponseManager,?SocketServer";
????????????Console.WriteLine("反射類名為:"?+?typeName);
????????????Type?type?=?Type.GetType(typeName);
????????????if?(type?==?null)
????????????{
????????????????return;
????????????}
????????????var?manager?=?Activator.CreateInstance(type)?as?IResponseManager;
????????????manager.Write(sender,?this.socketClientSesson.Select(s?=>?s.Key).ToList(),
????????????????request.Param?as?IDictionary<string,?object>);
????????}
????}
?
?
最后,json數據傳輸的實體對象為:
?
???[Serializable]????public?class?SocketRequest
????{
????????public?string?Method?{?get;?set;?}
????????public?string?DateTime?{?get;?set;?}
????????public?object?Param?{?get;?set;?}
????}
?
?
????[Serializable]????public?class?SocketResponse
????{
????????public?string?Method?{?get;?set;?}
????????public?string?DateTime?{?get;?set;?}
????????public?object?Result?{?get;?set;?}
????}
?
?四、客戶端源代碼
1.布局文件
logon.xml:
?
<?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"?android:background="@drawable/background">
????<LinearLayout?android:orientation="vertical"
????????android:layout_width="fill_parent"?android:layout_height="60dip"
????????android:background="@drawable/logon"?/>
????<LinearLayout?android:orientation="vertical"
????????android:layout_width="fill_parent"?android:layout_height="fill_parent"
????????android:paddingLeft="10dp"?android:paddingRight="10dp">
????????<View?android:layout_width="fill_parent"?android:layout_height="20dip"?/>
????????<TextView?android:id="@+id/feedback_title"?android:textColor="#FFFFFF"
????????????android:layout_width="fill_parent"?android:layout_height="wrap_content"
????????????android:text="用戶名:"?/>
????????<EditText?android:id="@+id/edtUserName"?android:layout_width="fill_parent"
????????????android:layout_height="wrap_content"?/>
????????<View?android:layout_width="fill_parent"?android:layout_height="2dip"
????????????android:background="#FF909090"?/>
????????<TextView?android:layout_width="fill_parent"
????????????android:textColor="#FFFFFF"?android:layout_height="wrap_content"
????????????android:text="IP地址:"?/>
????????<EditText?android:id="@+id/edtIp"?android:layout_width="fill_parent"
????????????android:layout_height="wrap_content"?android:digits="1234567890."?
????????????android:text="192.168.1.101"/>
????????<View?android:layout_width="fill_parent"?android:layout_height="2dip"
????????????android:background="#FF909090"?/>
????????<TextView?android:layout_width="fill_parent"
????????????android:textColor="#FFFFFF"?android:layout_height="wrap_content"
????????????android:text="端口號:"?/>
????????<EditText?android:id="@+id/edtPort"?android:layout_width="fill_parent"
????????????android:layout_height="wrap_content"?android:inputType="number"
????????????android:numeric="integer"?android:text="1234"/>
????????<LinearLayout?android:orientation="horizontal"
????????????android:layout_width="fill_parent"?android:layout_height="wrap_content"
????????????android:layout_marginTop="10dp">
????????</LinearLayout>
????????<RelativeLayout?android:layout_width="fill_parent"
????????????android:layout_height="fill_parent">
????????????<View?android:id="@+id/feedback_content"?android:layout_width="fill_parent"
????????????????android:layout_height="fill_parent"?android:maxEms="10"
????????????????android:minEms="10"?android:gravity="top"
????????????????android:layout_marginBottom="50dip"?/>
????????????<Button?android:id="@+id/btnLogon"?android:layout_width="fill_parent"
????????????????android:layout_height="50dp"?android:text="登陸"?android:textSize="19dp"
????????????????android:layout_gravity="center_horizontal"
????????????????android:layout_alignParentBottom="true"?/>
????????</RelativeLayout>
????</LinearLayout>
</LinearLayout>
?
main.xml:
<?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"?android:background="@drawable/background">
????<ListView?android:layout_width="fill_parent"
????????android:layout_height="wrap_content"?android:id="@+id/ltvMessage">
????</ListView>
????<RelativeLayout?android:layout_width="fill_parent"
????????android:layout_height="wrap_content">
????????<EditText?android:layout_width="fill_parent"
????????????android:layout_height="wrap_content"?android:id="@+id/edtMessage"
????????????android:hint="請輸入消息"?android:layout_alignTop="@+id/btnSend"
????????????android:layout_toLeftOf="@+id/btnSend"?/>
????????<Button?android:text="SEND"?android:id="@+id/btnSend"
????????????android:layout_height="wrap_content"?android:layout_width="wrap_content"
????????????android:layout_alignParentRight="true"?/>
????</RelativeLayout>
</LinearLayout>
?
listview_item.xml:
?
<?xml?version="1.0"?encoding="utf-8"?><LinearLayout?xmlns:android="http://schemas.android.com/apk/res/android"
????android:layout_width="fill_parent"?android:layout_height="wrap_content"
????android:orientation="vertical"?android:paddingBottom="3dip"
????android:paddingLeft="10dip">
????<TextView?android:layout_height="wrap_content"
????????android:layout_width="fill_parent"?android:id="@+id/itmMessage"
????????android:textSize="20dip">
????</TextView>
????<LinearLayout?android:layout_width="fill_parent"
????????android:orientation="horizontal"?android:layout_height="20dip">
????????<TextView?android:layout_height="fill_parent"
????????????android:layout_width="100dip"?android:id="@+id/itmUserName"?>
????????</TextView>
????????<TextView?android:layout_height="fill_parent"
????????????android:layout_width="200dip"?android:id="@+id/itmTime"?>
????????</TextView>
????</LinearLayout>
</LinearLayout>
?
SocketClient:
?
package?ld.socket;import?java.io.BufferedReader;
import?java.io.BufferedWriter;
import?java.io.IOException;
import?java.io.InputStreamReader;
import?java.io.OutputStreamWriter;
import?java.net.Socket;
import?java.net.UnknownHostException;
import?java.text.SimpleDateFormat;
import?java.util.Date;
import?java.util.HashMap;
import?java.util.Map;
import?org.json.JSONArray;
import?org.json.JSONException;
import?org.json.JSONObject;
import?android.os.Handler;
import?android.os.Message;
import?android.util.Log;
public?class?SocketClient?{
????private?static?Socket?client;
????private?static?SocketClient?instance?=?null;
????public?static?SocketClient?getInstance()?{
????????if?(instance?==?null)?{
????????????synchronized?(ChartInfo.class)?{
????????????????if?(instance?==?null)?{
????????????????????try?{
????????????????????????ChartInfo?chartInfo?=?ChartInfo.getInstance();
????????????????????????client?=?new?Socket(chartInfo.getIp(),?chartInfo
????????????????????????????????.getPort());
????????????????????????instance?=?new?SocketClient();
????????????????????}?catch?(UnknownHostException?e)?{
????????????????????????//?TODO?Auto-generated?catch?block
????????????????????}?catch?(IOException?e)?{
????????????????????????//?TODO?Auto-generated?catch?block
????????????????????}
????????????????}
????????????}
????????}
????????return?instance;
????}
????private?SocketClient()?{
????????this.initMap();
????????this.startThread();
????}
????private?void?initMap()?{
????????this.handlerMap?=?new?HashMap<String,?Handler>();
????}
????public?void?close()?{
????????try?{
????????????client.close();
????????}?catch?(IOException?e)?{
????????????//?TODO?Auto-generated?catch?block
????????????//e.printStackTrace();
????????}
????????instance?=?null;
????}
????
????private?void?startThread()?{
????????Thread?thread?=?new?Thread()?{
????????????@Override
????????????public?void?run()?{
????????????????while?(true)?{
????????????????????if?(client?==?null?||?!client.isConnected())?{
????????????????????????continue;
????????????????????}
????????????????????BufferedReader?reader;
????????????????????try?{
????????????????????????reader?=?new?BufferedReader(new?InputStreamReader(
????????????????????????????????client.getInputStream()));
????????????????????????String?line?=?reader.readLine();
????????????????????????Log.d("initSocket",?"line:"?+?line);
????????????????????????if?(line.equals(""))?{
????????????????????????????continue;
????????????????????????}
????????????????????????JSONObject?json?=?new?JSONObject(line);
????????????????????????String?method?=?json.getString("Method");
????????????????????????Log.d("initSocket",?"method:"?+?method);
????????????????????????if?(method.equals("")
????????????????????????????????||?!handlerMap.containsKey(method))?{
????????????????????????????Log.d("initSocket",?"handlerMap?not?method");
????????????????????????????continue;
????????????????????????}
????????????????????????Handler?handler?=?handlerMap.get(method);
????????????????????????if?(handler?==?null)?{
????????????????????????????Log.d("initSocket",?"handler?is?null");
????????????????????????????continue;
????????????????????????}
????????????????????????Log.d("initSocket",?"handler:"?+?method);
????????????????????????Object?obj?=?json.getJSONObject("Result");
????????????????????????Log.d("initSocket",?"Result:"?+?obj);
????????????????????????Message?msg?=?new?Message();
????????????????????????msg.obj?=?obj;
????????????????????????handler.sendMessage(msg);
????????????????????}?catch?(IOException?e)?{
????????????????????}?catch?(JSONException?e)?{
????????????????????}
????????????????}
????????????}
????????};
????????thread.start();
????}
????private?Map<String,?Handler>?handlerMap;
????public?void?putHandler(String?methodnName,?Handler?handler)?{
????????this.removeHandler(methodnName);
????????this.handlerMap.put(methodnName,?handler);
????}
????public?void?removeHandler(String?methodnName)?{
????????if?(this.handlerMap.containsKey(methodnName))?{
????????????this.handlerMap.remove(methodnName);
????????}
????}
????public?void?logon(String?userName)?{
????????Log.d("initSocket",?"logon");
????????try?{
????????????OutputStreamWriter?osw?=?new?OutputStreamWriter(client
????????????????????.getOutputStream());
????????????BufferedWriter?writer?=?new?BufferedWriter(osw);
????????????JSONObject?param?=?new?JSONObject();
????????????param.put("UserName",?userName.replace("\n",?"?"));
????????????JSONObject?json?=?this.getJSONData("Logon",?param);
????????????writer.write(json.toString());
????????????writer.flush();
????????}?catch?(IOException?e)?{
????????????//?TODO?Auto-generated?catch?block
????????????e.printStackTrace();
????????}?catch?(JSONException?e)?{
????????????//?TODO?Auto-generated?catch?block
????????????e.printStackTrace();
????????}
????}
????public?void?sendMessage(String?message)?{
????????Log.d("initSocket",?"Send");
????????try?{
????????????OutputStreamWriter?osw?=?new?OutputStreamWriter(client
????????????????????.getOutputStream());
????????????BufferedWriter?writer?=?new?BufferedWriter(osw);
????????????JSONArray?array?=?new?JSONArray();
????????????for?(String?item?:?message.split("\n"))?{
????????????????array.put(item);
????????????}
????????????JSONObject?param?=?new?JSONObject();
????????????param.put("Message",?array);
????????????param.put("UserName",?ChartInfo.getInstance().getUserName());
????????????JSONObject?json?=?this.getJSONData("Send",?param);
????????????writer.write(json.toString());
????????????writer.flush();
????????}?catch?(IOException?e)?{
????????????//?TODO?Auto-generated?catch?block
????????????e.printStackTrace();
????????}?catch?(JSONException?e)?{
????????????//?TODO?Auto-generated?catch?block
????????????e.printStackTrace();
????????}
????}
????private?JSONObject?getJSONData(String?methodName,?JSONObject?param)?{
????????JSONObject?json?=?new?JSONObject();
????????try?{
????????????json.put("Method",?methodName);
????????????SimpleDateFormat?format?=?new?SimpleDateFormat(
????????????????????"yyyy-MM-dd?HH:mm:ss");
????????????json.put("DateTime",?format.format(new?Date()));
????????????json.put("Param",?param);
????????????return?json;
????????}?catch?(JSONException?e)?{
????????????return?null;
????????}
????}
}
?
LogonActivity:
?
package?ld.socket;import?org.json.JSONException;
import?org.json.JSONObject;
import?android.app.Activity;
import?android.app.AlertDialog;
import?android.content.ComponentName;
import?android.content.DialogInterface;
import?android.content.Intent;
import?android.os.Bundle;
import?android.os.Handler;
import?android.os.Message;
import?android.util.Log;
import?android.view.KeyEvent;
import?android.view.View;
import?android.view.View.OnClickListener;
import?android.widget.Button;
import?android.widget.EditText;
public?class?LogonActivity?extends?Activity?{
????private?EditText?edtUserName;
????private?EditText?edtIp;
????private?EditText?edtPort;
????private?Button?btnLogon;
????@Override
????protected?void?onCreate(Bundle?savedInstanceState)?{
????????//?TODO?Auto-generated?method?stub
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.logon);
????????this.initViews();
????}
????private?void?initViews()?{
????????this.edtUserName?=?(EditText)?this.findViewById(R.id.edtUserName);
????????this.edtIp?=?(EditText)?this.findViewById(R.id.edtIp);
????????this.edtPort?=?(EditText)?this.findViewById(R.id.edtPort);
????????this.btnLogon?=?(Button)?this.findViewById(R.id.btnLogon);
????????this.btnLogon.setOnClickListener(new?OnClickListener()?{
????????????@Override
????????????public?void?onClick(View?v)?{
????????????????//?TODO?Auto-generated?method?stub
????????????????//?showAlert(edtUserName.getText().toString());
????????????????if?(edtUserName.getText().toString().equals(""))?{
????????????????????showDialog("請輸入用戶名");
????????????????????return;
????????????????}
????????????????if?(edtIp.getText().toString().equals(""))?{
????????????????????showDialog("請輸入IP地址");
????????????????????return;
????????????????}
????????????????if?(edtPort.getText().toString().equals(""))?{
????????????????????showDialog("請輸入端口號");
????????????????????return;
????????????????}
????????????????int?port?=?Integer.parseInt(edtPort.getText().toString());
????????????????ChartInfo?chartInfo?=?ChartInfo.getInstance();
????????????????chartInfo.setIp(edtIp.getText().toString());
????????????????chartInfo.setPort(port);
????????????????SocketClient?proxy?=?SocketClient.getInstance();
????????????????if?(proxy?==?null)?{
????????????????????showDialog("未接入互聯網");
????????????????????setWireless();
????????????????????return;
????????????????}
????????????????proxy.putHandler("Logon",?new?Handler()?{
????????????????????@Override
????????????????????public?void?handleMessage(Message?msg)?{
????????????????????????SocketClient?proxy?=?SocketClient.getInstance();
????????????????????????proxy.removeHandler("Logon");
????????????????????????Log.d("initSocket",?"handleMessage");
????????????????????????if?(msg?==?null?||?msg.obj?==?null)?{
????????????????????????????return;
????????????????????????}
????????????????????????JSONObject?json?=?(JSONObject)?msg.obj;
????????????????????????try?{
????????????????????????????String?userName?=?json.getString("UserName");
????????????????????????????Log.d("initSocket",?"userName:"?+?userName);
????????????????????????????ChartInfo.getInstance().setUserName(userName);
????????????????????????????Intent?itt?=?new?Intent();
????????????????????????????itt
????????????????????????????????????.setClass(LogonActivity.this,
????????????????????????????????????????????MainActivity.class);
????????????????????????????LogonActivity.this.startActivity(itt);
????????????????????????}?catch?(JSONException?e)?{
????????????????????????????//?TODO?Auto-generated?catch?block
????????????????????????????e.printStackTrace();
????????????????????????}
????????????????????}
????????????????});
????????????????proxy.logon(edtUserName.getText().toString());
????????????}
????????});
????}
????private?void?setWireless()?{
????????Intent?mIntent?=?new?Intent("/");
????????ComponentName?comp?=?new?ComponentName("com.android.settings",
????????????????"com.android.settings.WirelessSettings");
????????mIntent.setComponent(comp);
????????mIntent.setAction("android.intent.action.VIEW");
????????startActivityForResult(mIntent,?0);
????}
????private?void?showDialog(String?mess)?{
????????new?AlertDialog.Builder(this).setTitle("信息").setMessage(mess)
????????????????.setNegativeButton("確定",?new?DialogInterface.OnClickListener()?{
????????????????????public?void?onClick(DialogInterface?dialog,?int?which)?{
????????????????????}
????????????????}).show();
????}
????@Override
????public?boolean?onKeyDown(int?keyCode,?KeyEvent?event)?{
????????if?(keyCode?==?KeyEvent.KEYCODE_BACK?&&?event.getRepeatCount()?==?0)?{
????????????AlertDialog?alertDialog?=?new?AlertDialog.Builder(
????????????????????LogonActivity.this).setTitle("退出程序").setMessage("是否退出程序")
????????????????????.setPositiveButton("確定",
????????????????????????????new?DialogInterface.OnClickListener()?{
????????????????????????????????public?void?onClick(DialogInterface?dialog,
????????????????????????????????????????int?which)?{
????????????????????????????????????LogonActivity.this.finish();
????????????????????????????????}
????????????????????????????}).setNegativeButton("取消",
????????????????????new?DialogInterface.OnClickListener()?{
????????????????????????public?void?onClick(DialogInterface?dialog,?int?which)?{
????????????????????????????return;
????????????????????????}
????????????????????}).create();?//?創建對話框
????????????alertDialog.show();?//?顯示對話框
????????????return?false;
????????}
????????return?false;
????}
????@Override
????protected?void?onDestroy()?{
????????//?TODO?Auto-generated?method?stub
????????super.onDestroy();
????????SocketClient?proxy?=?SocketClient.getInstance();
????????if?(proxy?!=?null)?{
????????????proxy.close();
????????}
????}
}
?
?
MainActivity:
?
package?ld.socket;import?org.json.JSONException;
import?org.json.JSONObject;
import?android.app.Activity;
import?android.app.AlertDialog;
import?android.content.DialogInterface;
import?android.os.Bundle;
import?android.os.Handler;
import?android.os.Message;
import?android.util.Log;
import?android.view.KeyEvent;
import?android.view.View;
import?android.view.WindowManager;
import?android.view.View.OnClickListener;
import?android.widget.Button;
import?android.widget.EditText;
import?android.widget.ListView;
public?class?MainActivity?extends?Activity?{
????private?EditText?edtMessage;
????private?Button?btnSend;
????private?ListView?ltvMessage;
????private?MessageAdapter?adapter;
????/**?Called?when?the?activity?is?first?created.?*/
????@Override
????public?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????setContentView(R.layout.main);
????????//?隱藏鍵盤
????????this.getWindow().setSoftInputMode(
????????????????WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
????????Log.d("initSocket",?"MessageAdapter");
????????this.adapter?=?new?MessageAdapter(this);
????????Log.d("initSocket",?"adapter?is?ok");
????????this.findThisViews();
????????this.initHandler();
????????this.serOnClick();
????????Log.d("initSocket",?"onCreate");
????}
????private?void?findThisViews()?{
????????this.edtMessage?=?(EditText)?this.findViewById(R.id.edtMessage);
????????this.btnSend?=?(Button)?this.findViewById(R.id.btnSend);
????????this.ltvMessage?=?(ListView)?this.findViewById(R.id.ltvMessage);
????????//?this.ltvMessage.setEnabled(false);
????????this.ltvMessage.setAdapter(this.adapter);
????}
????private?void?initHandler()?{
????????Handler?handler?=?new?Handler()?{
????????????@Override
????????????public?void?handleMessage(Message?msg)?{
????????????????if?(msg.obj?==?null)?{
????????????????????Log.d("initSocket",?"handleMessage?is?null");
????????????????????return;
????????????????}
????????????????Log.d("initSocket",?"handleMessage");
????????????????try?{
????????????????????JSONObject?json?=?(JSONObject)?msg.obj;
????????????????????String?userName?=?json.getString("UserName");
????????????????????StringBuilder?sb?=?new?StringBuilder();
????????????????????int?length?=?json.getJSONArray("Message").length();
????????????????????for?(int?i?=?0;?i?<?length;?i++)?{
????????????????????????String?item?=?json.getJSONArray("Message").getString(i);
????????????????????????if?(item.equals(""))?{
????????????????????????????continue;
????????????????????????}
????????????????????????if?(length?>?i?+?1)?{
????????????????????????????Log.d("initSocket",?"length:"?+?length);
????????????????????????????Log.d("initSocket",?"i:"?+?i);
????????????????????????????Log.d("initSocket",?"item:"?+?item);
????????????????????????????item?+=?"\n";
????????????????????????}
????????????????????????sb.append(item);
????????????????????}
????????????????????MessageRecord?record?=?new?MessageRecord();
????????????????????record.setUserName(userName);
????????????????????record.setMessage(sb.toString());
????????????????????MainActivity.this.adapter.add(record);
????????????????????adapter.notifyDataSetChanged();
????????????????}?catch?(JSONException?e)?{
????????????????????//?TODO?Auto-generated?catch?block
????????????????????e.printStackTrace();
????????????????}
????????????}
????????};
????????SocketClient?proxy?=?SocketClient.getInstance();
????????proxy.putHandler("Send",?handler);
????}
????private?void?serOnClick()?{
????????this.btnSend.setOnClickListener(new?OnClickListener()?{
????????????@Override
????????????public?void?onClick(View?v)?{
????????????????//?TODO?Auto-generated?method?stub
????????????????btnSend.setEnabled(false);
????????????????String?txt?=?edtMessage.getText().toString();
????????????????if?(txt.equals(""))?{
????????????????????btnSend.setEnabled(true);
????????????????????return;
????????????????}
????????????????SocketClient?proxy?=?SocketClient.getInstance();
????????????????proxy.sendMessage(txt);
????????????????edtMessage.setText("");
????????????????btnSend.setEnabled(true);
????????????}
????????});
????}
????@Override
????public?boolean?onKeyDown(int?keyCode,?KeyEvent?event)?{
????????if?(keyCode?==?KeyEvent.KEYCODE_BACK?&&?event.getRepeatCount()?==?0)?{
????????????AlertDialog?alertDialog?=?new?AlertDialog.Builder(
????????????????????MainActivity.this).setTitle("詢問").setMessage("是否注銷登錄?")
????????????????????.setPositiveButton("確定",
????????????????????????????new?DialogInterface.OnClickListener()?{
????????????????????????????????public?void?onClick(DialogInterface?dialog,
????????????????????????????????????????int?which)?{
????????????????????????????????????MainActivity.this.finish();
????????????????????????????????}
????????????????????????????}).setNegativeButton("取消",
????????????????????new?DialogInterface.OnClickListener()?{
????????????????????????public?void?onClick(DialogInterface?dialog,?int?which)?{
????????????????????????????return;
????????????????????????}
????????????????????}).create();?//?創建對話框
????????????alertDialog.show();?//?顯示對話框
????????????return?false;
????????}
????????return?false;
????}
}
?
?五、運行效果
?
?
?
?
? 代碼下載
? 出處:http://www.cnblogs.com/GoodHelper/archive/2011/07/08/android_socket_chart.html
? 歡迎轉載,但需保留版權!
轉載于:https://www.cnblogs.com/GoodHelper/archive/2011/07/08/android_socket_chart.html
總結
以上是生活随笔為你收集整理的以C#编写的Socket服务器的Android手机聊天室Demo的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redmi Note 11T Pro可能
- 下一篇: 随笔03