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
沒有留言:
張貼留言