最近開始研究Socket編程,今天就把Socket編程的基礎知識整理一下以便於記錄和消化,內容比較基礎,但是我覺得Socket編程還是很重要的,所以就做了簡單的研究,有
些東西還沒怎麼懂,只好一邊學習一邊總結了,希望大家能喜歡啊!
一、IP地址操作類
1、IPAddress類
a、在該類中有一個 Parse()方法,可以把點分的十進制IP表示轉化成IPAddress類,方法如下:
IPAddress address = IPAddress.Parse(“192.168.0.1”);
b、IPAddress提供4個只讀字段
Any 用於代表本地系統可用的任何IP地址
Broadcase 用於代表本地網絡的IP廣播地址
Loopback 用於代表系統的回送地址
None 用於代表系統上沒有網絡接口其中IPAddress.Any最常用可以用來表示本機上所有的IP地址,這對於socket服務進行偵聽時,最方便使用,不用對每個IP進行偵聽了。
而IPAddress.Broadcase可用來UDP的IP廣播,這些具體講socket時再詳細介紹。
2、IPEndPoint類
我們可以通過二種構造方法來創建IPEndPoint類:
a、IPEndPoint(long address, int port)
b、IPEndPoint(IPAddress address, int port)四個屬性:Address 、AddressFamily、 Port 、MaxPort、 MinPort
這些應該從名字上就很好理解,不再一一介紹。IPEndPoint其實就是一個IP地址和端口的綁定,可以代表一個服務,用來Socket通訊。二、DNS相關類
DNS類有四個靜態方法,來獲取主機DNS相關信息,
1、GetHostName()
通過Dns.GetHostName()可以獲得本地計算機的主機名
2、GetHostByName()
根據主機名稱,返回一個IPHostEntry 對象:
IPHostEntry GetHostByName(string hostName)其中IPHostEntry把一個DNS主機名與一個別名和IP地址的數組相關聯,包含三個屬性: AddressList:一個IPAddress對象的數組 、Aliases:一個字符串對象數組、 HostName:一個用於主機名的字符串對象
3、GetHostByAddress()
類似於GetHostByName(),只不過這裡的參數是IP地址,而不是主機名,也返回一個IPHostEntry對象。
IPHostEntry GetHostByAddress(IPAddress address)
IPHostEntry GetHostByAddress(string address)
4、Resolve()
當我們不知道輸入的遠程主機的地址是哪種格式時(主機名或IP地址),用以上的二種方法來實現,我們可能還要通過判斷客戶輸入的格式,才能正確使用,但Dns類提供
一更簡單的方法Resolve(),該方法可以接受或者是主機名格式或者是IP地址格式的任何一種地址,並返回IPHostEntry對象。
三、Socket編程
對於Socket編程我們通常按照下面的步驟來進行:
A、服務端
1、創建IPEndPoint實例,用於Socket偵聽時綁定
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, 6001);
2、創建套接字實例
mServerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
3、將套接字和IPEndPoint綁定
mServerSocket.Bind(ipep);
4、設置套接字為收聽模式
mServerSocket.Listen(10);5、接收客戶端的連接並開啟一個線程來接收數據
while (true) { try { mClientSocket = mServerSocket.Accept(); mClientThread = new Thread(ReceiveData); mClientThread.Start(); } catch (Exception e) { Console.WriteLine("Socket通訊出現異常錯誤:" + e.Message); } }其中,接受數據的方法ReceiveData()定義如下:
////// 接受客戶端數據的方法 /// ///private static void ReceiveData() { bool keepActive = true; //客戶端Socket Socket mSocket = mClientSocket; //緩沖區大小 Byte[] buffer = new Byte[1024]; //獲取客戶端信息 IPEndPoint Clientipep = (IPEndPoint)mClientSocket.RemoteEndPoint; //輸出客戶端信息 Console.WriteLine("[系統]:客戶端" + Clientipep.Address + ":" + Clientipep.Port + "加入連接"); //等待客戶端響應 while (keepActive) { try { //獲取數據大小 mLength = mSocket.Available; //接受數據 mSocket.Receive(buffer, 0, mLength, SocketFlags.None); //判斷數據是否讀取完畢 if (mLength == 0) continue; } catch (Exception e) { Console.WriteLine("讀取數據出現異常:" + e.Message); } //輸出客戶端消息 Console.WriteLine("[客戶端]:"+ Encoding.Unicode.GetString(buffer).ToString());
//向客戶端發送數據 byte[] data = new byte[1024]; data = Encoding.Unicode.GetBytes("服務器收到!"); mSocket.Send(data, data.Length, SocketFlags.None);
和服務器端類似,直接給出代碼:
IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 6001); mClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { mClientSocket.Connect(ipep); if (mClientSocket.Connected) { Console.WriteLine("[系統]:客戶端已連接到服務器端,開始向服務器發送數據"); Console.WriteLine("[客戶端]:我是客戶端" + ipep.Address + ":" + ipep.Port + "我正在向服務器發送數據"); //向服務器發送數據 byte[] data = new byte[1024]; data = Encoding.Unicode.GetBytes("你好,服務器端,我是客戶端"); mClientSocket.Send(data, data.Length, SocketFlags.None); //提示用戶等待服務器響應 Console.WriteLine("[系統]:等待服務器響應......"); while (true) { mLength = 0; try { mLength = mClientSocket.Available; mClientSocket.Receive(mData, mLength, SocketFlags.None); if (mLength == 0) continue; } catch (Exception e) { Console.Write("讀取服務器數據失敗:" + e.Message); return; } Console.WriteLine("[服務器]:"+ Encoding.Unicode.GetString(mData).Substring(0, mLength).ToString()); } } } catch (Exception e) { Console.WriteLine("連接到服務器失敗:" + e.Message); return; }