引言
C#網絡編程系列文章計劃簡單地講述網絡編程方面的基礎知識,由於本人在這方面功力有限,所以只 能提供一些初步的入門知識,希望能對剛開始學習的朋友提供一些幫助。如果想要更加深入的內容,可以 參考相關書籍。
本文是該系列第一篇,主要講述了基於套接字(Socket)進行網絡編程的基本概念,其中包括TCP協議 、套接字、聊天程序的三種開發模式,以及兩個基本操作:偵聽端口、連接遠程服務端;第二篇講述了一 個簡單的范例:從客戶端傳輸字符串到服務端,服務端接收並打印字符串,將字符串改為大寫,然後再將 字符串回發到客戶端,客戶端最後打印傳回的字符串;第三篇是第二篇的一個強化,講述了第二篇中沒有 解決的一個問題,並使用了異步傳輸的方式來完成和第二篇同樣的功能;第四篇則演示了如何在客戶端與 服務端之間收發文件;第五篇實現了一個能夠在線聊天並進行文件傳輸的聊天程序,實際上是對前面知識 的一個綜合應用。
與本文相關的還有一篇文章是:C#編寫簡單的聊天程序,但這個聊天程序不及本系列中的聊天程序功 能強大,實現方式也不相同。
網絡編程基本概念
1.面向連接的傳輸協議:TCP
對於TCP協議我不想說太多東西,這屬於大學課程,又涉及計算機科學,而我不是“學院派”,對於這 部分內容,我覺得作為開發人員,只需要掌握與程序相關的概念就可以了,不需要做太艱深的研究。
我們首先知道TCP是面向連接的,它的意思是說兩個遠程主機(或者叫進程,因為實際上遠程通信是進 程之間的通信,而進程則是運行中的程序),必須首先進行一個握手過程,確認連接成功,之後才能傳輸 實際的數據。比如說進程A想將字符串“It's a fine day today”發給進程B,它首先要建立連接。在這 一過程中,它首先需要知道進程B的位置(主機地址和端口號)。隨後發送一個不包含實際數據的請求報 文,我們可以將這個報文稱之為“hello”。如果進程B接收到了這個“hello”,就向進程A回復一個 “hello”,進程A隨後才發送實際的數據“It's a fine day today”。
關於TCP第二個需要了解的,就是它是全雙工的。意思是說如果兩個主機上的進程(比如進程A、進程B ),一旦建立好連接,那麼數據就既可以由A流向B,也可以由B流向A。除此以外,它還是點對點的,意思 是說一個TCP連接總是兩者之間的,在發送中,通過一個連接將數據發給多個接收方是不可能的。TCP還有 一個特性,就是稱為可靠的數據傳輸,意思是連接建立後,數據的發送一定能夠到達,並且是有序的,就 是說發的時候你發了ABC,那麼收的一方收到的也一定是ABC,而不會是BCA或者別的什麼。
編程中與TCP相關的最重要的一個概念就是套接字。我們應該知道網絡七層協議,如果我們將上面的應 用程、表示層、會話層籠統地算作一層(有的教材便是如此劃分的),那麼我們編寫的網絡應用程序就位 於應用層,而大家知道TCP是屬於傳輸層的協議,那麼我們在應用層如何使用傳輸層的服務呢(消息發送 或者文件上傳下載)?大家知道在應用程序中我們用接口來分離實現,在應用層和傳輸層之間,則是使用 套接字來進行分離。它就像是傳輸層為應用層開的一個小口,應用程序通過這個小口向遠程發送數據,或 者接收遠程發來的數據;而這個小口以內,也就是數據進入這個口之後,或者數據從這個口出來之前,我 們是不知道也不需要知道的,我們也不會關心它如何傳輸,這屬於網絡其它層次的工作。
舉個例子,如果你想寫封郵件發給遠方的朋友,那麼你如何寫信、將信打包,屬於應用層,信怎麼寫 ,怎麼打包完全由我們做主;而當我們將信投入郵筒時,郵筒的那個口就是套接字,在進入套接字之後, 就是傳輸層、網絡層等(郵局、公路交管或者航線等)其它層次的工作了。我們從來不會去關心信是如何 從西安發往北京的,我們只知道寫好了投入郵筒就OK了。可以用下面這兩幅圖來表示它: