| 
NOTE!! 
The source code is deprecated! Please go to my Github: KarateJB/DotNetCore.Socket.Sample, for the latest Socket Server/Client sample code. 
注意!! 
本文中的程式碼已經過時,請您參考我Github上的最新Socket Server/Client範例程式碼:KarateJB/DotNetCore.Socket.Sample | 
一開始仍先放上整個Server-client架構供參考 …
1.1  
為了讓Socket Server開始Listening後,仍可顯示連線的Client資訊。 故建立Socket
Server後,使用BackgroundWorker來開啟Socket Server。
1.2  
此Socket Server每次接收到新的Client要求時,再開另一條Thread來處理上傳的資料。
1.3  
處理完畢後,回傳訊息給Client。
1.4  
結束Client的連線。
1.5  
(重要) 關閉Socket Server時,要先停止Socket Listener (即第一點的BackgroundWorker),才能關閉Socket Server。
= > = > = > 開始實作Socket
Server。
2.1  
將上傳檔案名稱及其內容拆成[檔案名稱長度][檔案名稱] [檔案內容],存成Byte Array。
2.2  
建立TcpClient或Socket物件來連線Socket Server。
2.3  
資料上傳完畢,利用NetworkStream來接收Server端回傳的訊息。
2.4  
斷線。
= > = > = > 開始實作Socket
Client。
一、 方案參考
1.    UploadSocket.Common
: 只有放Log4Net module
2.    UploadSocket.Infra
: Model
3.    UploadSocket.Service
: 
l  封裝Socket的類別
(UploadServer)
l  Client連線後的事件處理
(ClientHandler)
4.    Server
and Client as WinForm application
二、Client side
1.   
Global
We
will have one file for upload-testing.
| 
private String
  uploadaFileFullPath = @"D:\UploadFile.txt"; | 
2.   
Use System.Net.Sockets.Socket to build connection
l   按下【SocketClient連線】的事件
| 
private void
  bt_ConnSocketClick(object sender, EventArgs e) 
{ 
            //Make IP end point same as Server. 
            IPAddress[] ipAddress = Dns.GetHostAddresses("localhost"); 
            IPEndPoint ipEnd = new IPEndPoint(ipAddress[1], 5656); 
            Socket clientSocket = null; 
            try 
            { 
                //Make a client socket to send data
  to server. 
                clientSocket = new Socket( 
                    AddressFamily.InterNetwork, 
                    SocketType.Stream, ProtocolType.IP); 
                //連線到Socket Server 
                clientSocket.Connect(ipEnd); 
                //取得檔案轉成要送出的資料格式 
                var byteData = this.getFileByteArray();
   
                #region Send without callback 
                //clientSocket.Send(byteData); 
                #endregion 
                #region Send with callback 
                clientSocket.BeginSend( 
                    byteData, 0,
  byteData.Length, 0, 
                    new AsyncCallback(sendCallback), clientSocket); 
                #endregion 
                //取得Server傳回的訊息 
                String rtnMsg = String.Empty; 
                NetworkStream serverStream = new NetworkStream(clientSocket); 
                this.getServerReturnData( 
serverStream,
  clientSocket.ReceiveBufferSize, out rtnMsg); 
                tb_ServerRMsg.Text = rtnMsg;             
} 
            catch (Exception ex){ 
                // Exception handling … } 
            finally{ 
                ipAddress = null; 
                ipEnd = null; 
                clientSocket.Close(); 
                clientSocket.Dispose(); 
            } 
} | 
l   取得Server傳回的資料 (訊息)
| 
private void
  getServerReturnData( 
NetworkStream serverStream, int dataLength, out String serverMsg) 
{ 
//讀取 socket server 回傳值並轉為 string 
byte[] inStream = new byte[10025]; 
serverStream.Read(inStream, 0,
  dataLength); 
serverMsg= System.Text.Encoding.UTF8.GetString(inStream); 
} | 
l   取得檔案轉成要送出的資料格式
| 
private byte[]
  getFileByteArray() 
{                 
/* 取得檔案名稱 和 路徑 */ 
uploadaFileFullPath =
  uploadaFileFullPath.Replace("\\", "/"); 
String fileName = Path.GetFileName(uploadaFileFullPath);
   
//讀取檔案名稱並轉為Byte[] 
byte[] fileNameByte = Encoding.ASCII.GetBytes(fileName); 
      //讀取檔案內容並轉為Byte[] 
byte[] fileData = File.ReadAllBytes(filePath
  + fileName); 
      //取得檔案名稱的長度並轉為Byte[] 
byte[] fileNameLen =  
Encoding.ASCII.GetBytes(fileNameByte.Length.ToString()); 
//定義 clientData : 存放[檔案名稱長度][檔案名稱] [檔案內容] 
byte[] clientData =  
new byte[4 + fileNameByte.Length +
  fileData.Length]; 
//開始放入資料到 clientData : 存放 
//[檔案名稱長度 byte0~3][檔案名稱 byte4~7] [檔案內容 byte7~] 
fileNameLen.CopyTo(clientData, 0); 
fileNameByte.CopyTo(clientData, 4); 
fileData.CopyTo(clientData, 4 +
  fileNameByte.Length); 
return clientData; 
} | 
l   Callback
| 
private void sendCallback(IAsyncResult ar) 
{  
Debug.WriteLine("Callback!"); 
} | 
1.    Use System.Net.Sockets.TcpClient to
build connection
l   按下【TcpClient連線】的事件
| 
private void bt_ConnTcpClick(object sender, EventArgs e) 
{ 
//遠端 socket server IP 位址 
String remoteIpAddress = "127.0.0.1"; 
//遠端 socket server 所監聽的 port number 
int remotePortNumber = 5656; 
TcpClient tcpClient = null; 
try{ 
        //初始化Socket client 
tcpClient = new TcpClient(); 
tcpClient.Connect(remoteIpAddress,
  remotePortNumber); 
//取得用來傳送訊息至 socket server 的 stream 物件 
NetworkStream serverStream =
  tcpClient.GetStream(); 
//將資料轉為 byte[] 
byte[] outStream = getFileByteArray(); 
//將資料寫入 stream object (表示傳送資料至 socket server) 
serverStream.Write(outStream, 0,
  outStream.Length); 
serverStream.Flush(); 
//讀取 socket server 回傳值並轉為 string 
String rtnMsg = String.Empty; 
this.getServerReturnData( 
serverStream,
  tcpClient.ReceiveBufferSize, out rtnMsg); 
//顯示Server回傳訊息 
tb_ServerRMsg.Text = rtndata; 
} 
catch (Exception ex){ } 
finally{ 
tcpClient.Close(); 
tcpClient = null; 
} 
} | 
三、 Server
side : Snapshot




 
沒有留言:
張貼留言