Socket套接字:客戶端與服務端進行通訊

客戶端與服務端進行通訊的協議是Tcp/Ip,咱們客戶端與服務端實現數據通訊除了協議的支持外,還須要一個Socket套接字的應用。下面我將我學習Socket的的這個例子:實現客戶端與服務端通訊,來給你們一看分享學習一下: 第一:這是WinForm環境下的,首先是一個佈局,客戶端和服務端各一個WinForm。 第二:客戶端要想鏈接服務端,首先我得有一個IP,得有一個端口號,因此我服務端能夠這樣來安排,因爲是本地練習,因此IP固定爲:127.0.0.1 端口號固定爲:5000,這裏我能夠開始寫個人監聽事件了,首先我建立一個Socket套接字WatchSocket,用建立好的套接字去關聯IP、端口,並綁定,設置監聽隊列。具體服務端設置監聽的代碼以下:數組

Socket WatchSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
IPAddress ipAddress = IPAddress.Parse(txtIP.Text); IPEndPoint endPoint = new IPEndPoint(ipAddress, Convert.ToInt32(txtDK.Text)); 
WatchSocket.Bind(endPoint); 
WatchSocket.Listen(10);

其中,Socket參數分別表明:尋址協議,以流的方式傳輸,採用TCP協議。 而下面綁定的好比,txtIP 、 txtDK 則表明WinForm中相對於的屬性Name,很少解釋。 到這裏,咱們服務端綁定了Socket以後,客戶端呢,客戶端一樣也須要鏈接服務端,這樣二者才能達到鏈接與被鏈接狀態,具體客戶端鏈接代碼以下:多線程

Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
 IPAddress ipAddress = IPAddress.Parse(txtIP.Text); IPEndPoint endPoint = new IPEndPoint(ipAddress, Convert.ToInt32(txtDK.Text));
 clientSocket.Connect(endPoint);

是否是感受客戶端Socket鏈接與服務端Socket建立都差很少,對的,就是這樣。只不過一個是鏈接,一個是監聽。 寫到這裏,讀者能夠延伸一下,給一些更醒目的提示,在這裏就不說了。 第三:客戶端與服務端鏈接成功後,就應該交互數據了,那麼咱們首先來看看客戶端向服務端發送數據 一樣,WinForm界面上的處理也是給他一個文本框用於存儲數據,一個按鈕用於發送時觸發,我首先須要獲取發送的內容,而後將內容轉換成byte字節的形式發送,發送成功後,清空文本框內容,代碼以下:函數

string str = txtSend.Text; byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str); clientSocket.Send(buffer); txtSend.Text = "";

 

是否是代碼很簡單呢,這個時候,我客戶端的數據就已經發送到服務端了,服務端固然得接收了,讓咱們一塊兒來看看服務端是怎麼接收客戶端發送過來的數據的。接收是用的Accept,因爲接收時會涉及到多線程的問題,而且接收狀態爲While(true){ } 表示我隨時在接收,可是,接收時,總得找個地方吧,一樣,在服務端接收數據時也須要建立一個byte數組,給他一個內存空間,好比1M,因爲我傳過來的是字節流形式,那麼我服務端首先須要用Receive接收到客戶端發送過來的字節流數據,將其存入緩衝區,而後將其轉換成String類型,顯示到界面上,具體接收代碼以下:佈局

byte[] buffer = new byte[1024 * 1024]; string msg = System.Text.Encoding.UTF8.GetString(buffer);

 

是否是感受代碼很簡單呀,只要知道了這個思路,代碼其實沒什麼難的。 第四:既然客戶端能夠向服務端發送數據,那麼服務端一樣也能夠向客戶端發送數據,道理同樣,就不單獨說了,這裏咱們說一下服務端向多個客戶端羣發數據。 首先服務端向多個客戶端羣發,無非就是讓多個客戶端鏈接上服務端,服務端獲取這些客戶端的IP和端口號,而後遍歷發送,IP咱們用的是本地固定的,端口號更不用說了,通常咱們要超過1024以避免重複。思路分享以下:在一個ListBox裏面經過集合獲取鏈接的多個客戶端,將每一個客戶端的IP顯示到服務端的ListBox集合裏面。因爲每一個客戶端鏈接是都是經過Socket綁定IP和端口來實現,因此能夠用一個Dictionary集合來把綁定的IP、端口,Socket給獲取。如:學習

Dictionary<string, Socket> dicSocket = new Dictionary<string, Socket>();
 while(true)
 {
Socket newSocket = WatchSocket.Accept(); dicSocket.Add(newSocket.RemoteEndPoint.ToString(), newSocket); txtLsb.Items.Add(newSocket.RemoteEndPoint.ToString()); 
}

 

這樣,我就把每一個客戶端給獲取到了,羣發時無非就是就是遍歷循環ListBox,而後發送,代碼以下:this

string msg = txtSendAll.Text; 
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(msg); foreach (string item in txtLsb.Items)
 { 
dicSocket[item].Send(buffer); 
} 
txtSendAll.Text = "";

 

同理,客戶端接收時,也是先在內存中找一個地方,而後把接收到的字節流轉換成字符串給顯示到界面,代碼以下:spa

byte[] buffer = new byte[1024 * 1024];
 int recLength = clientSocket.Receive(buffer); 
string msg = System.Text.Encoding.UTF8.GetString(buffer, 0, recLength);

 

這個時候羣發搞定。 第五:上述只是寫到了字符串的發過來發過去,我如今想要發一個文件怎麼辦,應該怎麼作呢,讓咱們一塊兒來看一下,從客戶端發送一個文件到服務端。 首先,界面上的得有一個打開文件的按鈕,一個發送文件的按鈕,一個現實發送文件名字的一個Text; 其次,打開文件用OpenFileDialog ,獲取文件名稱將其顯示到Text中,這個就很少說了。 而後,是發送文件,一樣我也是把文件轉換到一個字節數組裏面,將字節流發送過去,用到了FileStream,代碼分享以下:線程

byte[] buffer = new byte[1024 * 1024]; 
using (FileStream fs = new FileStream(this.txtSendFile.Text, FileMode.Open)) 
{ 
int readLength = fs.Read(buffer, 0, buffer.Length); byte[] newBuffer = new byte[readLength + 1];
 newBuffer[0] = 1;
 Buffer.BlockCopy(buffer, 0, newBuffer, 1, readLength); clientSocket.Send(newBuffer); 
}

 

其中我把這個字節數組又給建立了一個newBuffer,目的是爲了服務端接收文件的時候,區分出來到底接收的是字符串仍是文件,其中把第一個字節賦值爲1表示文件。 那麼服務端開始接收客戶端發送過來的文件了,發送成功,開始接收以前,須要建立一個另存爲對話框,SaveFileDialog,代碼以下:code

SaveFileDialog sf = new SaveFileDialog(); 
if (DialogResult.OK == sf.ShowDialog())//彈出一個另存爲對話框 
{ 
string fileName = sf.FileName; 
using (FileStream fs = new FileStream(fileName, FileMode.Create)) //寫入磁盤 
{
 fs.Write(buffer, 1, recLength - 1);
 } 
}

 

此時,整個客戶端與服務端的通訊就到這了。 其中有兩個地方沒有花力氣去說,orm

第一:多線程時,要在窗口構造函數中,把微軟的這個TextBox.CheckForIllegalCrossThreadCalls = false;設置一下。

第二:涉及到多線程問題時,好比,客戶端發送數據,服務端接收數據等,會碰到單線程不能反應的問題,這個時候用多線程控制能夠解決,關於多線程的問題,會單獨列出來分享。

這裏主要把Socket實現客戶端與服務端通訊給介紹一下。但願你們多多指點,一塊兒學習。

相關文章
相關標籤/搜索