回覆列表
-
1 # 寫程式設計師的程式碼
-
2 # BWanger軟體開發達人
這個問題點非常好。但問的不是很明確。
你肯定是想問socket傳輸資料時,接收方如何知道接收的是字串還是二進位制值。一是靠事先約定的協議,一般用於控制中的資料傳輸;二是採用標準協議(如HTTP),用於網際網路。如果沒有事先的約定,你無法確定接收到的資料是文字、影象還是音訊或影片。因此,必須事先約定Socket接收資料的格式。約定既可以採用標準協議(如HTTP),也可以用自己定義的協議。
以下透過我之前做的程式設計實類,分別說明:
事先約定協議:二進位制與字串事先寫好格式,與檔案讀/寫一樣。SOCKET傳輸字串還是其它資料型別,由你在程式設計的send()函式中決定,其資料型別為void*,void *為“無型別指標”,void *可以指向任何型別的資料,也就是說可以用字串,也可以用二進位制的int,double等。
TCP/IP,UDP傳輸協議,用socket程式設計並建立socket關鍵字來實現網路間的通訊。
如下圖是windows的一個socket程式設計。
從其send,recv函式的格式看,與C/VC++的fread/fwrite()函式非常一致,只是把流換成socket套接字了:
HTTP客戶端請求:要複雜,必須按照HTTP標準協議做。以客戶端為例。
客戶端傳送一個HTTP請求到伺服器的請求訊息包括以下格式:請求行(request line)、請求頭部(header)、空行和請求資料四個部分組成,下圖給出了請求報文的一般格式。
程式設計實倒:
從上面看出,程式設計與windows,linux迥然不同。
要了解socket傳輸型別,還是要了解什麼是socket。這裡我以java的應用來說一下。
java中的socket在使用java的socket時,它是一種基於TCP/IP的協議通訊,TCP/IP本身也有自己的底層協議包裝,不過這僅僅是底層的通訊交換規則,但是沒有包含自己想要告訴對方的一些頭部資訊(例如想要告訴對方內容的長度、格式)。
socket原理Socket實質上提供了程序通訊的端點。程序通訊之前,雙方首先必須各自建立一個端點,否則是沒有辦法建立聯絡並相互通訊的。正如打電話之前,雙方必須各自擁有一臺電話機一樣。
伺服器監聽:是伺服器端套接字並不定位具體的客戶端套接字,而是處於等待連線的狀態,實時監控網路狀態。客戶端請求:是指由客戶端的套接字提出連線請求,要連線的目標是伺服器端的套接字。為此,客戶端的套接字必須首先描述它要連線的伺服器的套接字,指出伺服器端套接字的地址和埠號,然後就向伺服器端套接字提出連線請求。連線確認:是指當伺服器端套接字監聽到或者說接收到客戶端套接字的連線請求,它就響應客戶端套接字的請求,建立一個新的執行緒,把伺服器端套接字的描述發給客戶端,一旦客戶端確認了此描述,連線就建立好了。而伺服器端套接字繼續處於監聽狀態,繼續接收其他客戶端套接字的連線請求。基於java的socket網路程式設計實現Server端Listen監聽某個埠是否有連線請求,Client端向Server 端發出連線請求,Server端向Client端發回Accept接受訊息。這樣一個連線就建立起來了。Server端和Client端都可以透過Send,Write等方法與對方通訊。
對於一個功能齊全的Socket,都要包含以下基本結構,其工作過程包含以下四個基本的步驟:
建立socket。開啟連線到Socket的輸入/出流。按照一定的協議對Socket進行讀/寫操作。關閉socket。總結透過對socket的理解可以看出它的傳輸型別不管是字串還是其它,底層都是二進位制流,無論你用什麼流去讀都是讀同樣的資料,宣告兩個輸出流輸出後,對於客戶端還是隻能看到一個流輸入,不會給你分開的。所以這裡你開兩個子程序讀,就會出現誰執行快就把資料讀出來了,而且看你PrintWriter也沒有flush,所以應該只傳輸了list資料,客戶端BufferedReader先執行,就把資料讀出來了。