- 有 server & client 兩端
- server 只有一個,而 client 有可能會多個
- server 可設定監聽(listen)的 port number
以下直接用範例來說明囉!
(其中 SocketServer 跟新的 client 連線後,會交給 ClientRequestHandler 處理)
SocketServer.cs
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using System.Net; using System.ComponentModel; namespace SocketConn { class SocketServer { #region private property ////// socket server TCP port number /// private int _PortNumber; ////// TCP Listener /// private TcpListener _Listener; ////// 用來處理 Listener 工作的執行緒 /// private BackgroundWorker _bgwServer = new BackgroundWorker(); ////// socker client 識別編號 /// private int _ClientNo = 0; #endregion #region static public property ////// 工作進行中產生之訊息 /// public static ListsMessages = new List (); #endregion #region constructor /// /// constructor /// /// socket server TCP port number public SocketServer(int inPortNumber) { this._PortNumber = inPortNumber; //委派事件 _bgwServer.DoWork += new DoWorkEventHandler(_bgwServer_DoWork); } #endregion #region public method ////// 開始監聽 /// public void Start() { if (!_bgwServer.IsBusy) _bgwServer.RunWorkerAsync(); } #endregion #region BackgroundWorker ////// 處理 Listener 工作 /// /// /// private void _bgwServer_DoWork(object sender, DoWorkEventArgs e) { try { //若 TCP Listner 正在工作,則停止 if (_Listener != null) _Listener.Stop(); //初始化 TCPListener _Listener = new TcpListener(IPAddress.Any, _PortNumber); //啟動 listener _Listener.Start(); sMessages.Add(" >> " + "Server Started"); //========== 持續接受監聽 socket client 的連線 ========== (start) while (true) { //監聽到來自 socket client 的連線要求 TcpClient socket4Client = _Listener.AcceptTcpClient(); //累加 socket client 識別編號 _ClientNo++; sMessages.Add(" >> " + "Client Request No:" + Convert.ToString(_ClientNo) + " started!"); //產生 BackgroundWorker 負責處理每一個 Socket Client 的要求 ClientRequestHandler handler = new ClientRequestHandler(_ClientNo, socket4Client); handler.DoCommunicate(); } //========== 持續接受監聽 socket client 的連線 ========== (end) } catch (Exception exp) { sMessages.Add(exp.ToString()); } } #endregion } }
ClientRequestHandler.cs
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using System.ComponentModel; namespace SocketConn { class ClientRequestHandler { #region private property ////// socket client 識別號碼 /// private int _ClientNo; ////// socket client reuqest /// private TcpClient _TcpClient; #endregion #region constructor ////// constructor /// /// socket client 識別號碼 /// socket client reuqest public ClientRequestHandler(int inClientNo, TcpClient inTcpClient) { this._ClientNo = inClientNo; this._TcpClient = inTcpClient; } #endregion #region public method ////// server & client 間相互進行通訊 /// public void DoCommunicate() { //產生 BackgroundWorker 負責處理每一個 socket client 的 reuqest BackgroundWorker bgwSocket = new BackgroundWorker(); bgwSocket.DoWork += new DoWorkEventHandler(bgwSocket_DoWork); bgwSocket.RunWorkerAsync(); } #endregion #region BackgroundWorker ////// 處理 socket client request /// private void bgwSocket_DoWork(object sender, DoWorkEventArgs e) { //server & client 已經連線完成 while (_TcpClient.Connected) { //取得網路串流物件,取得來自 socket client 的訊息 NetworkStream netStream = _TcpClient.GetStream(); byte[] readBuffer = new byte[1024]; int count = 0; if ((count = netStream.Read(readBuffer, 0, readBuffer.Length)) != 0) { string clientRequest = Encoding.UTF8.GetString(readBuffer, 0, count); SocketServer.sMessages.Add(" >> " + "From client(" + _ClientNo + ") =>" + clientRequest); //正確取得 client requst,再回傳給 client string serverResponse = "Server to clinet(" + _ClientNo + ") => message: " + clientRequest; byte[] sendBytes = Encoding.UTF8.GetBytes(serverResponse); netStream.Write(sendBytes, 0, sendBytes.Length); netStream.Flush(); SocketServer.sMessages.Add(" >> " + serverResponse); } } } #endregion } }
SocketClient.cs
using System; using System.Collections.Generic; using System.Text; using System.Net; using System.Net.Sockets; namespace SocketConn { class SocketClient { #region private property ////// 遠端 socket server IP 位址 /// private string _RemoteIpAddress; ////// 遠端 socket server 所監聽的 port number /// private int _RemotePortNumber; ////// socket client 物件(連接遠端 socket server 用) /// private TcpClient _TcpClient; #endregion #region public static property public static ListsMessages = new List (); #endregion #region constructor /// /// constructor /// /// 遠端 socket server IP 位址 /// 遠端 socket server 所監聽的 port number public SocketClient(string inRemoteIpAddr, int inRemotePortNum) { this._RemoteIpAddress = inRemoteIpAddr; this._RemotePortNumber = inRemotePortNum; } #endregion #region public method ////// 連線至 socket server /// public void Connect() { //初始化 socket client _TcpClient = new TcpClient(); _TcpClient.Connect(_RemoteIpAddress, _RemotePortNumber); sMessages.Add("Client Socket Program - Server Connected ..."); } ////// 傳送訊息至 socker server /// /// 訊息 ///socker server 回傳結果 public string Send(string inMessage) { try { //取得用來傳送訊息至 socket server 的 stream 物件 NetworkStream serverStream = _TcpClient.GetStream(); //將資料轉為 byte[] byte[] outStream = System.Text.Encoding.UTF8.GetBytes(inMessage); //將資料寫入 stream object (表示傳送資料至 socket server) serverStream.Write(outStream, 0, outStream.Length); serverStream.Flush(); //讀取 socket server 回傳值並轉為 string byte[] inStream = new byte[10025]; serverStream.Read(inStream, 0, (int)_TcpClient.ReceiveBufferSize); string returndata = System.Text.Encoding.UTF8.GetString(inStream); sMessages.Add("Data from Server : " + returndata); return returndata; } catch (Exception exp) { sMessages.Add(exp.ToString()); return exp.ToString(); } } #endregion } }
public static List sMessages = new List();
回覆刪除public static List sMessages = new List();
回覆刪除請問MAIN()裡需要先放哪些函式??~.~
回覆刪除作者已經移除這則留言。
回覆刪除public static List sMessages = new List();
回覆刪除型別被吃掉了
參照
http://dreamtails.pixnet.net/blog/post/23947420-c%23-%E8%A3%A1-list%E7%94%A8%E6%B3%95%EF%BC%8C%E6%9C%89%E9%BB%9E%E5%83%8F%E6%98%AF%E4%B8%8D%E7%94%A8%E5%AE%A3%E5%91%8A%E9%95%B7%E5%BA%A6%E7%9A%84%E9%99%A3%E5%88%97(