這幾天倒騰socket編程,在部落格園找到了張子陽大哥的socket編程的系列文章 看了很不錯 。
網上也有許多類似的文章,我這裡也純屬炒剩飯 。獻醜了哈
首先還是用tcpListener 跟tcpClient吧 先把基礎的搞懂了再說
socket編程的概念用我們以前老師的話說就是一個類似打電話 或者管子 的概念。
為什麼是打電話捏,如果要建立串連( 打電話) 另外一端不會知道你什麼時候會打給他 可能馬上也可能過很久,就是說始終有一方要一直守在那裡 等待接入 這就是tcpListener
也就是服務端總是要使用tcplistener。
下面看一下建立最基本的建立tcpListener:
static void Main(string[] args){ //在原生6500連接埠上建立偵聽 TcpListener listener = new TcpListener(6500); listener.Start(); ConsoleKey key; Console.WriteLine("請按Q鍵退出!!"); do { key = Console.ReadKey().Key; } while (key != ConsoleKey.Q);}
程式運行後 在命令列使用 netstat -a 可看到如下資訊:
別忘了加上張子陽大哥的那幾句“請按Q鍵退出”的代碼 ,要不然閃一下就過了看不到任何效果。
下面我們來一個用戶端連伺服器 然後從服務端接收一個字串的例子:
服務端:
static void Main(string[] args){ //在原生6500連接埠上建立偵聽 TcpListener listener = new TcpListener(6500); //啟動偵聽 listener.Start(); Console.WriteLine("server is running..."); while (true) { //處理新的接入 TcpClient client = listener.AcceptTcpClient(); NetworkStream stream = client.GetStream(); string str = "MrXiang"; stream.Write(Encoding.ASCII.GetBytes(str), 0, str.Length); }}
用戶端:
static void Main(string[] args){ //遠程主機ip+連接埠 IPAddress ip = new IPAddress(new byte[] { 127, 0, 0, 1 }); IPEndPoint port = new IPEndPoint(ip, 6500); TcpClient client = new TcpClient(); //建立串連 client.Connect(port); //System.Threading.Thread.Sleep(1000); NetworkStream stream = client.GetStream(); byte[] data = new byte[client.Available]; stream.Read(data, 0, data.Length); Console.WriteLine(Encoding.ASCII.GetString(data)); ConsoleKey key; Console.WriteLine("請按Q鍵退出!!"); do { key = Console.ReadKey().Key; } while (key != ConsoleKey.Q);}
怎麼樣簡單吧,先運行服務端 然後運行用戶端
但是在用戶端你會發現有時候你收不到字串 (要看運氣了)有時後又收得到:
你調用 client.Available 屬性探索每次都是0 也就是說沒有任何資料可供讀取。
然後把那句 //System.Threading.Thread.Sleep(1000); 注釋去掉 。保證每次都會收到字串
這是為什麼捏 ,且聽貧僧娓娓道來:
本來兩端有各自的tcpClient對象 他們之間是沒有任何瓜葛的(這不廢話嗎 兩台電腦上) 你讀你的資料 我寫我的資料,並且讀還不一定就讀得到資料 因為他們之間
根本就是不同步的 你不能要求別人什麼時候在另一端把資料寫入,就算另一端在指定時間把資料寫入了 網路問題 延遲啥的
各種問題紛繁複雜 都不能保證你在什麼時間一定會收到資料(這就是上面為什麼要使用sleep 來等待服務端務必把資料發送完整了才進行讀取)
我們能做的只能是建立一個串連(那個啥子3次握手 啥的 俺也不懂) 然後一直在那個串連上收發位元據 實在等得受不鳥了就 哢嚓, 僅此而已 這就是socket
我們往socket這個封裝好的“郵筒”裡投郵件 收郵件,至於郵件能不能送到 什麼時候送到 這些我們都不能控制
但是他們兩端用的tcpClient 卻又有某種關聯 好像就是一個一樣,就好像一根“管子”把兩個tcpClient串連起來了 一邊讀另一邊就寫
而他們之間來來往往的是位元據 嗯“管子”一個形象的比喻
執行一次串連就會有“一對”連接埠出現 因為一個服務端 一個用戶端
但是這些“管子”通通是建立在tcpListener之上的