一Socket介紹: 網路上的兩個程式通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。 建立網路通信連接至少要一對埠號(socket)。socket本質是編程介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式員做網路開發所用的介面,這就是Socket編程接 ...
一Socket介紹:
網路上的兩個程式通過一個雙向的通信連接實現數據的交換,這個連接的一端稱為一個socket。
建立網路通信連接至少要一對埠號(socket)。socket本質是編程介面(API),對TCP/IP的封裝,TCP/IP也要提供可供程式員做網路開發所用的介面,這就是Socket編程介面;HTTP是轎車,提供了封裝或者顯示數據的具體形式;Socket是發動機,提供了網路通信的能力。
Socket在英文原意椒"孔"或者"插座",作為BSD UNIX ,取後一種意思。通常也稱作"套接字",用於描述IP地址和埠,是一個通信鏈的句柄,可以用來實現不同虛擬機或不同電腦之間的通信。在Internet上的主機一般運行了多個服務軟體,同時提供幾種服務。每種服務都打開一個Socket,並綁定到一個埠上,不同的埠對應於不同的服務。Socket正如其英文原義那樣,像一個多孔插座。一臺主機猶如佈滿各種插座的房間,每個插座有一個編號,有的插座提供220伏交流電, 有的提供110伏交流電,有的則提供有線電視節目。 客戶軟體將插頭插到不同編號的插座,就可以得到不同的服務。
--------說一個簡單的例子
大學里男生要去找自己的女朋友,但是女朋友在宿舍,他又沒有手機,因為是女生宿舍男生又不能直接去找女生。他只能通過宿舍阿姨去聯繫女生。這個阿姨就是Socket。男生女生通過阿姨進行通信。在或者我們打電話和別人聯繫。手機也是。
在來看看我代碼里的Socket 做了哪些處理。
鄙人不才,畫了這個麽一個圖。
大致意思就是客戶端有一個Socket對象,向服務端發送請求。服務端有一個專門負責監聽的Socket,監聽的Socket監聽到了有請求的時候就會為這個請求創建一個與之對應通信的Socket進行通信。
接下來講講Socket類
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);
首先看看Socket類的構造函數的三個參數。
AddressFamily 這個參數制定了尋找地址的方案。Socket通過他確定如果解析地址,比如地址設置了IPv4,Socket就會通過Ipv4的規則去解析地址,如果是IPV6就會通過Ipv6規則去解析地址。
AddressFamily 這個枚舉的具體有哪些值可以看MSDN。這裡附上傳送門----->點擊這裡
SocketType 這個參數看名字就是知道幹啥用了。Socke Type 就是設置Socket類型,這個參數是與最後一個參數有關聯。這裡附上傳送門------->點擊這裡
protocolType 這個參數設置Socket之間的通信協議,就是通信規則,就是類似抗戰時期地下工作都有暗號一樣。天王蓋地虎,寶塔偵鎮河妖,只有口號對上了才是自己人,他們都有自己的規則。
Socket也一樣,也需要規定一種口號,一種協議。常見有TCP協議,和UDP協議。這裡附上傳送門------->點擊這裡
註意:SocketType 有時會隱式指示在 AddressFamily 中使用哪個 ProtocolType。例如,當 SocketType 為 Dgram 時,ProtocolType 始終為 Udp。當 SocketType 為 Stream 時,ProtocolType 始終為 Tcp。如果試圖使用不相容的組合創建 Socket,則 Socket 將引發 SocketException。
下麵開始掏出一手代碼進行說明瞭
服務端代碼
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SocketTest { class Program { static void Main(string[] args) { Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPAddress ip = IPAddress.Any; IPEndPoint point = new IPEndPoint(ip, 255);//設置Socket服務端接受請求的Ip和服務端的埠號 socketWatch.Bind(point);//進行綁定 Console.WriteLine("正在監聽中。。。。。"); Thread therad = new Thread(listen); socketWatch.Listen(10); therad.Start(socketWatch); } static void listen(object obj) { Socket socket = obj as Socket; while (true) { //等待請求返回,並且創建一個與客戶端通信的請求(如果這句話寫在主線程里,而且沒有請求過來,主線程會卡死,因為它會一直等待) Socket socketsend = socket.Accept(); //socketsend.RemoteEndPoint 或者請求的Ip地址 Console.WriteLine(socketsend.RemoteEndPoint.ToString() + "已經連接上來啦"); byte[] byte0 = new byte[1024 * 102]; int count = socketsend.Receive(byte0); string str = Encoding.UTF8.GetString(byte0); Console.WriteLine("收到客戶端"+ socketsend.RemoteEndPoint.ToString()+"發來的小時:"+str); //測試用For迴圈發三次消息給已經連接的客戶端 for (int i = 0; i < 3; i++) { string sMsg = "我是服務端,你已經連接上來了,重要的事情說三遍"; byte[] bytes = Encoding.UTF8.GetBytes(sMsg); socketsend.Send(bytes); //Send方法是發送消息 Thread.Sleep(1000); } } } } }
客戶端代碼
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SocketClient { class Program { static void Main(string[] args) { Socket socketclient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //設置連接服務端的Ip IPAddress address = IPAddress.Parse("127.0.0.1"); //設置連接服務端的埠 IPEndPoint point = new IPEndPoint(address, 255); //連接 socketclient.Connect(point); byte[] arrRecvmsg = new byte[1024 * 1024]; arrRecvmsg = Encoding.UTF8.GetBytes("我是客戶端,我要連接你!!"); //發送消息 socketclient.Send(arrRecvmsg); Console.WriteLine("正在連接服務端"); //開啟線程接受消息 Thread th = new Thread(GetMessage); th.Start(socketclient); Console.ReadKey(); } static void GetMessage(object obj) { byte[] arrRecvmsg = new byte[1024*1024]; Socket socketclient = obj as Socket; while (true)//開啟迴圈 一直讀取客戶端發來的消息 { int length = socketclient.Receive(arrRecvmsg);//讀取消息 string str = Encoding.UTF8.GetString(arrRecvmsg, 0, length); Console.WriteLine("收到服務端發來的消息:"+str); } } } }
運行效果
OK!簡單應用就是這樣啦。以上代碼是學習的Demo,不能用於實際應用,只能用來學習,實際應用要複雜的很多。
由於本人也是渣渣菜鳥,以上可敘述可能有錯誤。如有發現,還請告之。
大家一起學習進步。