大家好,關(guān)于java socket編程步驟很多朋友都還不太明白,今天小編就來為大家分享關(guān)于完成一個socket客戶端程序的知識,希望對各位有所幫助!
如何學編程
編程是編定程序的中文簡稱,就是讓計算機代碼解決某個問題,對某個計算體系規(guī)定一定的運算方式,使計算體系按照該計算方式運行,并最終得到相應(yīng)結(jié)果的過程。編程能提高邏輯思維能力,加強計算能力。
編程語言
Python
Python是一種面向?qū)ο笥兄a簡潔、可讀性強特點的解釋型計算機程序設(shè)計語言。代碼簡潔是因為它把許多的復(fù)雜的操作封裝起來,將C語言中麻煩的指針和內(nèi)存管理對開發(fā)者隱藏起來,使得在開發(fā)過程中,無須在意這部分的細節(jié)。另外Python這門語言強制用戶用縮進進行排版,若不好好排版,則代碼編譯無法通過,或者運行過程會出現(xiàn)錯誤。
C語言
C語言是一門面向過程的、抽象化的廣泛應(yīng)用于底層開發(fā)的通用程序設(shè)計語言,能以簡易的方式編譯和處理低級存儲器。C語言既具有高級語言的特點,又具有匯編語言的特點,是僅產(chǎn)生少量機器語言以及不需要任何運行環(huán)境支持便能運行的高效率程序設(shè)計語言。
是有簡潔的語言、具有結(jié)構(gòu)化的控制語句、豐富的數(shù)據(jù)類型、豐富的運算符、可對物理地址進行直接操作、代碼具有較好的可移植性、可生成高質(zhì)量、目標代碼執(zhí)行效率高的程序。
Java
Java通過面向作為靜態(tài)對象的編程語言的代表,可以充分的實現(xiàn)面向的對象理論的編程語言,有簡單性、功能強大、分布式、健壯性、安全性、平臺獨立與可移植性、多線程及動態(tài)性的特點。
Java支持在網(wǎng)絡(luò)上應(yīng)用,Java既支持各種層次的網(wǎng)絡(luò)連接,又以Socket類支持可靠的流(stream)網(wǎng)絡(luò)連接,它是分布式語言。所以用戶可以產(chǎn)生分布式的客戶機和服務(wù)器。網(wǎng)絡(luò)變成軟件應(yīng)用的分布運載工具。Java程序只要編寫一次,就可到處運行。
PHP
PHP是一種被廣泛應(yīng)用的開放源代碼的多用途腳本語言,它可嵌入到HTML中,尤其適合web開發(fā)。
使用PHP的最大的好處是它對于初學者來說極其簡單,同時也給專業(yè)的程序員提供了各種高級的特性,只需幾個小時就可以自己寫一些簡單的腳本。盡管PHP的開發(fā)是以服務(wù)端腳本為目的,但事實上其功能遠不局限于此。
GO
Go語言(又稱Golang)是一種靜態(tài)強類型、編譯型語言,是一個開源編程環(huán)境,可以輕松構(gòu)建簡單、可靠和高效的軟件。Go語言語法與C相近,但功能上有:內(nèi)存安全,GC(垃圾回收),結(jié)構(gòu)形態(tài)及CSP-style并發(fā)計算。Go內(nèi)嵌了關(guān)聯(lián)數(shù)組(也稱為哈希表(Hashes)或字典(Dictionaries)),就像字符串類型一樣。
對比
python和c語言的區(qū)別主要體現(xiàn)在:語言類型、內(nèi)存管理、速度、應(yīng)用、運行、對象、聲明、測試和調(diào)試難度、復(fù)雜度、學習程度。測試和調(diào)試難度不同:Python相對其他語言而言是非常簡單的語言,高度集成,代碼量少。Python中的測試和調(diào)試更容易;C中測試和調(diào)試更難。學習難度不同:Python:Python程序更易于學習,編寫和閱讀;C語言:C程序語法比Python更難。
python跟java一樣是強類型語言,也就是說它不會根據(jù)環(huán)境變化自動改變數(shù)據(jù)類型。python是動態(tài)語言,而java是靜態(tài)語言。也就是說python在編程時,永遠不用給任何變量指定數(shù)據(jù)類型,而java寫程序時必須聲明所有變量的數(shù)據(jù)類型。
python的模塊類似于java的class,不過python模塊導入會執(zhí)行代碼的內(nèi)容,而java不會。python與java的執(zhí)行方式還是蠻像的,都是將源碼編譯成bytecode然后交給相應(yīng)的虛擬機去執(zhí)行。
Python的框架數(shù)量較少,而PHP中成熟的框架比較多;PHP是面向web的語言,而Python是多用途語言,也可以用于web開發(fā);Python使用非常嚴格的縮進強制執(zhí)行,使它比PHP更具可讀性。
學習思路
認識編程
編程語言(programminglanguage)又稱程序設(shè)計語言,是一組用特定語言編寫的用于執(zhí)行特定任務(wù)的指令。主要用于開發(fā)桌面應(yīng)用、操作系統(tǒng)、網(wǎng)站、移動應(yīng)用等。
低級編程語言
它基于二進制數(shù)0和1工作,處理器直接運行低級程序,不需要編譯器或解釋器,因此用低級語言編寫的程序可以運行得非??臁?/p>
低級語言進一步分為兩部分
機器語言
機器語言也稱為機器代碼或目標代碼,更容易閱讀,因為它通常以二進制或十六進制形式(基數(shù)16)形式顯示。
它不需要翻譯器來轉(zhuǎn)換程序,因為計算機直接理解機器語言程序。
匯編語言
匯編語言是為特定處理器設(shè)計的,它以象征性和人類可理解的形式表示一組指令。它使用匯編程序?qū)R編語言轉(zhuǎn)換為機器語言。
中級編程語言
中級編程語言介于低級編程語言和高級編程語言之間。
它也被稱為中間程序語言和偽語言。
中級編程語言的優(yōu)點是支持高級編程的特性,是一種用戶友好的語言,與機器語言和人類語言密切相關(guān)。
例如:C、C++
高級編程語言
高級編程語言(HLL)旨在開發(fā)用戶友好的軟件程序和網(wǎng)站。
這種編程語言需要編譯器或解釋器將程序翻譯成機器語言(執(zhí)行程序)。
示例:Python、Java、JavaScript、PHP、C#、C++等。
編程實踐
學習編程語言的過程簡單描述為:過、抄、仿、改、調(diào)、看、練、創(chuàng)、悟。
過
基礎(chǔ)知識點不求深解,語言什么樣的,適用場合、基本語法格式
抄代碼
從書上抄、例子中抄、邊抄邊想邊想邊回憶語法
模仿改
仿照給出的代碼寫出自己的代碼
勤調(diào)試
不斷調(diào)試驗證自己想法,繼續(xù)思考,再次驗證。熟悉調(diào)試工具調(diào)試方法
看n遍
出錯或者遇到問題時,將代碼從頭到尾看n遍直到快記住,找出問題原因
練
2-5步三遍以上
創(chuàng)新
拿出一個沒有寫過的根據(jù)要求,一步一步寫出來,寫不出來參考6
悟
主動找到寫代碼的感覺和成就感,保持下去。
選擇大于努力,只有切入一個適合自己的開發(fā)方向,才能持續(xù)進步。關(guān)于開發(fā)方向,我有以下兩個選擇標準。
興趣
學習編程是一個非??菰锏倪^程,內(nèi)容多,時間長,成本高,即使報名了培訓班也學不會,所以,我們首先要選擇自己感興趣的一個開發(fā)方向,這樣不但能快速學習,以后還能持續(xù)進步。學習編程的過程是比較艱苦的,沒有興趣很難硬抗下來,此處的興趣,是指別人無法撼動的熱愛,是工作之余讓你放松的事情。如果你只是有過某種想法,別人告訴你這個想法不靠譜,你就放棄了,這頂多是一時的雞血。
學習方式
費曼學習法
在學完一個東西之后去給別人講明白,注意是講給別人聽,當你寫成文章發(fā)表在網(wǎng)上的時候,你自然會去用更通俗的語言,更清晰的邏輯去講述這個事物背后的邏輯。這個過程是對自己學習的一個檢驗,也是加深映像整理思路的重要過程。
那么如果你是去記筆記的話,很有可能你會傾向于去照抄,或是不完全照抄,以“提綱”或是“知識點”的形式抄在本子上。說句實話,照抄的筆記真的沒用,因為現(xiàn)在搜索引擎的能力已經(jīng)可以讓你把大多數(shù)東西快速找到,你為什么還要照抄到筆記本上呢?
從功利的角度考慮,技術(shù)文章的寫作,別人可以直接訪問,也可以逐漸累積你的影響力,一個好的個人技術(shù)博客,會給你的簡歷加分很多,而一個厚厚的筆記本,沒有人會管你記了什么。
做好筆記
大多數(shù)人沒有過目不忘的神技,學了也不一定馬上掌握,需要過后花時間慢慢領(lǐng)悟,而且還有忘掉的風險,所以對于重要的知識點都要做好筆記。編程的過程中總會遇到各種各樣的問題,比如編程環(huán)境的配置,常用的快捷鍵,編程過程中的錯誤、異常,軟件更新問題等等。面對這些問題都是如何解決的,一定要記錄下來,一是增加自己解決問題的經(jīng)驗,而是以防下次出現(xiàn)。
多看官方文檔
外文資料互聯(lián)網(wǎng)是一個更新迭代很快的行業(yè),所有編程語言都會不斷的更新新功能和修復(fù)舊Bug,網(wǎng)上查的資料很有可能是舊的解決方案,現(xiàn)在已經(jīng)不適用了。所以最好最快的方法就是查看官方文檔。
進入行業(yè)圈子
只有進入行業(yè)圈子與其他人交流,你才了解最新的行業(yè)動態(tài),才知道自己需要更新哪些技能。
動手做項目
學習編程的最終目的就是用所學的做出具有一定功能的項目,而做項目又是最好的學習和鞏固知識的方式。如果前期能力不足就先做一些簡單的功能模塊,一步一步慢慢來,不要一開始就要實現(xiàn)各種酷炫炸天功能,遇到不會的就在網(wǎng)上查,現(xiàn)在互聯(lián)網(wǎng)這么發(fā)達,獲取資源也及其方便。而且開發(fā)前也最好在網(wǎng)上查一下有沒有已經(jīng)成型的框架或模板,什么都自己做一是很耗費時間,二是自己技術(shù)能力不足還可能留下不少坑。
學習Python
安裝編程環(huán)境
第一步:訪問Python官網(wǎng),獲取最新安裝程序。
第二步:運行下載的安裝程序,注意勾選“AddPython3.7toPATH”,然后選擇個性化安裝,即“Customizeinstallation”。
第三步:確?!皃ip”被勾選上,之后安裝各種庫需要用到pip。
第四步:高級選項,需要的可以修改安裝目錄,通常沒有需要修改的,直接點“Install”。
第五步:等待程序自動安裝完成。
第六步:出現(xiàn)如下界面,說明安裝已完成。
第七步:驗證方法,Windows+R鍵打開“運行”窗口,輸入cmd運行,進入命令提示窗口,再輸入python,進入Python的命令模式,輸入print("Hello"),結(jié)果輸出了Hello,如下圖所示,確定開發(fā)環(huán)境已安裝完成。
運行環(huán)境
HelloWorld!
命令行
在Linux命令行輸入:$python
將直接進入python。然后在命令行提示符>>>后面輸入:>>>print('HelloWorld!')
可以看到,隨后在屏幕上輸出:
HelloWorld!
print是一個常用函數(shù),其功能就是輸出括號中得字符串。
(在Python2.x中,print還可以是一個關(guān)鍵字,可寫成print'HelloWorld!',但這在3.x中行不通)
小程序
另一個使用Python的方法,是寫一個Python程序。用文本編輯器寫一個.py結(jié)尾的文件,比如說hello.py
在hello.py中寫入如下,并保存:print('HelloWorld!')
退出文本編輯器,然后在命令行輸入:$pythonhello.py
來運行hello.py??梢钥吹絇ython隨后輸出HelloWorld!
腳本
我們還可以把Python程序hello.py改成一個可執(zhí)行的腳本,直接執(zhí)行:#!/usr/bin/envpython
print('HelloWorld!')
需要修改上面程序的權(quán)限為可執(zhí)行:chmod755hello.py
然后再命令行中,輸入./hello.py
就可以直接運行了。
基本數(shù)據(jù)類型
變量不聲明
Python的變量不需要聲明,你可以直接輸入:>>>a=10
那么你的內(nèi)存里就有了一個變量a,它的值是10,它的類型是integer(整數(shù))。在此之前你不需要做什么特別的聲明,而數(shù)據(jù)類型是Python自動決定的。
>>>print(a)
>>>print(type(a))
那么會有如下輸出:
10
這里,我們學到一個內(nèi)置函數(shù)type(),用以查詢變量的類型。
回收變量名
如果你想讓a存儲不同的數(shù)據(jù),你不需要刪除原有變量就可以直接賦值。
>>>a=1.3
>>>print(a,type(a))
會有如下輸出
1.3
序列
sequence(序列)是一組有順序的元素的集合,(嚴格的說,是對象的集合,但鑒于我們還沒有引入“對象”概念,暫時說元素)序列可以包含一個或多個元素,也可以沒有任何元素。
我們之前所說的基本數(shù)據(jù)類型,都可以作為序列的元素。元素還可以是另一個序列,以及我們以后要介紹的其他對象。
序列有兩種:tuple(定值表;也有翻譯為元組)和list(表)
>>>s1=(2,1.3,'love',5.6,9,12,False)#s1是一個tuple
>>>s2=[True,5,'smile']#s2是一個list
>>>print(s1,type(s1))
>>>print(s2,type(s2))
tuple和list的主要區(qū)別在于,一旦建立,tuple的各個元素不可再變更,而list的各個元素可以再變更。
一個序列作為另一個序列的元素
>>>s3=[1,[3,4,5]]
空序列
>>>s4=[]
自學
網(wǎng)站
菜鳥網(wǎng)站
這個python教程很適合小白學習,沒有高深的原理,照著教程學就完事了。
菜鳥教程是一個提供免費編程學習的網(wǎng)站,里面不但能學到編程知識,還能運用在線編程工具,使你在學習的過程中得到發(fā)揮,實踐得真理,邊學邊做中讓基礎(chǔ)打得更穩(wěn),讓自己的知識更加穩(wěn)固。在自己有不明白不理解的地方可以在網(wǎng)站的用戶筆記中尋找大佬們的筆記,把自己所學和技術(shù)大佬的經(jīng)驗所融合,使自己更好地提升自己的能力。
菜鳥教程內(nèi)容豐富,例如前端熱門語言HTML5、CSS3、JavaScript、Vue等它該有的都有,都會從最基礎(chǔ)的開始教,讓剛學編程的小白由淺及深,一看就懂。每個知識點都有實例可以動手,直接在頁面內(nèi)做你想要的效果真的非常棒。菜鳥的排版簡潔清晰有序,內(nèi)容一針見血,讓你一看就能明白其知識點的含義。
菜鳥教程不僅前端教程語言豐富,后端的Java、PHP、Python更是一應(yīng)俱全,當然數(shù)據(jù)庫、移動端、XML、ASP.NET、WebService、開發(fā)工具和網(wǎng)站建設(shè)也是應(yīng)有盡有,菜鳥教程有學到的知識如此之多,奮斗吧少年。
廖雪峰的官方網(wǎng)站
廖雪峰的官方網(wǎng)站比較推薦新手程序員學習前端,這個網(wǎng)站的教學視頻的講解相對來說會比較生動,沒有其他教程那么死板,看起來也不至于那么犯困,也更便于新手去理解??偟膩碚f,廖雪峰的官方網(wǎng)站作為一款啟蒙類的前端學習網(wǎng)站還是相當不錯的。
Python官方教程
這是Python官方出品的教程,可搭配Python標準庫一起學。
書籍
《Python編程從入門到實踐(第2版)》
作者:埃里克·馬瑟斯(EricMatthes)袁國忠譯
ISBN:9787115546081
出版:人民郵電出版社
本書是針對所有層次Python讀者而作的Python門書。全書分兩部分:部分介紹用Python編程所必須了解的基本概念,包括強大的Python庫和工具,以及列表、字典、if語句、類、文件與異常、代碼測試等內(nèi)容;第二部分將理論付諸實踐,講解如何發(fā)三個項目,包括簡單的2D游戲、利用數(shù)據(jù)生成交互式的信息圖以及創(chuàng)建和定制簡單的Web應(yīng)用,并幫助讀者解決常見編程問題和困惑。
《像計算機科學家一樣學Python》
ISBN:9787115425515
作者:艾倫B.唐尼(AllenB.Downey)
出版:人民郵電出版社
本書以培養(yǎng)讀者以計算機科學家一樣的思維方式來理解Python語言編程。貫穿全書的主體是如何思考、設(shè)計、發(fā)的方法,而具體的編程語言,只是提供了一個具體場景方便介紹的媒介。全書共21章,詳細介紹Python語言編程的方方面面。本書從基本的編程概念始講起,包括語言的語法和語義,而且每個編程概念都有清晰的定義,引領(lǐng)讀者循序漸地學習變量、表達式、語句、函數(shù)和數(shù)據(jù)結(jié)構(gòu)。書中還探討了如何處理文件和數(shù)據(jù)庫,如何理解對象、方法和面向?qū)ο缶幊?,如何使用調(diào)試技巧來修正語法錯誤、運行時錯誤和語義錯誤。
《計算機科學叢書:Java編程思想》
ISBN:9787111213826
作者:[美]BruceEckel
出版:機械工業(yè)出版社
本書的作者擁有多年教學經(jīng)驗,對C、C++以及Java語言都有獨到、深入的見解,以通俗易懂及小而直接的示例解釋了一個個晦澀抽象的概念。本書共22章,包括操作符、控制執(zhí)行流程、訪問權(quán)限控制、復(fù)用類、多態(tài)、接口、通過異常處理錯誤、字符串、泛型、數(shù)組、容器深入研究、JavaI/O系統(tǒng)、枚舉類型、并發(fā)以及圖形化用戶界面等內(nèi)容。這些豐富的內(nèi)容,包含了Java語言基礎(chǔ)語法以及高級特性,適合各個層次的Java程序員閱讀,同時也是高等院校講授面向?qū)ο蟪绦蛟O(shè)計語言以及Java語言的好教材和參考書。
《瘋狂Java講義》
ISBN:9787121361586
作者:李剛
出版:電子工業(yè)出版社
《瘋狂Java講義(第4版)》深入介紹了Java編程的相關(guān)方面,《瘋狂Java講義(第4版)》內(nèi)容覆蓋了Java的基本語法結(jié)構(gòu)、Java的面向?qū)ο筇卣?、Java集合框架體系、Java泛型、異常處理、JavaGUI編程、JDBC數(shù)據(jù)庫編程、Java注釋、Java的IO流體系、Java多線程編程、Java網(wǎng)絡(luò)通信編程和Java反射機制。覆蓋了java.lang、java.util、java.text、java.io和java.nio、java.sql、java.awt、javax.swing包下絕大部分類和接口。本書重點介紹了Java9的模塊化系統(tǒng),還詳細介紹了Java9的jshell工具、多版本JAR包、匿名內(nèi)部類的菱形語法、增強的try語句、私有接口方法,以及Java9新增的各種API功能。
TCP/IP、HTTP、Socket和Servlet之間的邏輯關(guān)系、系統(tǒng)點是怎樣的
TCP/IP是計算機網(wǎng)絡(luò)通信中的傳輸層協(xié)議,在此之上是應(yīng)用層,HTTP是一種應(yīng)用層協(xié)議,除了HTTP還有多種應(yīng)用層協(xié)議,所有的應(yīng)用層都調(diào)用傳輸層協(xié)議的接口來進行數(shù)據(jù)傳輸。
Socket是編程接口,可以實現(xiàn)TCP/IP協(xié)議,進行網(wǎng)絡(luò)通信,也可以實現(xiàn)UDP協(xié)議。HTTP應(yīng)用都調(diào)用Socket接口來進行數(shù)據(jù)傳輸。
Servlet是java語言中的一種動態(tài)服務(wù)技術(shù),可以動態(tài)的響應(yīng)HTTP請求,雖然它也可以響應(yīng)其他應(yīng)用協(xié)議的請求,但最主要的用途還是HTTP。
網(wǎng)絡(luò)編程零基礎(chǔ)入門
回答如下:網(wǎng)絡(luò)編程是指在計算機網(wǎng)絡(luò)中進行數(shù)據(jù)傳輸和通信的編程技術(shù)。以下是網(wǎng)絡(luò)編程零基礎(chǔ)入門的步驟:
1.了解計算機網(wǎng)絡(luò)的基本概念,如IP地址、端口號、協(xié)議等。
2.學習一種編程語言,如Python、Java、C++等,掌握基本語法和數(shù)據(jù)類型。
3.學習網(wǎng)絡(luò)編程相關(guān)的庫和框架,如Python的socket、Java的Socket、C++的Boost.Asio等。
4.了解常用的網(wǎng)絡(luò)編程協(xié)議,如TCP、UDP、HTTP等。
5.編寫簡單的網(wǎng)絡(luò)程序,如客戶端和服務(wù)器端的交互、文件傳輸、聊天室等。
6.學習網(wǎng)絡(luò)安全相關(guān)知識,如加密、認證、授權(quán)等,以提高程序的安全性。
7.不斷實踐和深入學習網(wǎng)絡(luò)編程,掌握更多的技術(shù)和應(yīng)用場景。
“java.net.SocketException:Permissiondenied”如何解決
這是一個經(jīng)典錯誤,Socket不能對外連接,錯誤不會被報出,調(diào)試的時候,能看到Exception,一般是拋出java.net.socketexceptionpermissiondenied這個異常。只要你的程序想聯(lián)網(wǎng),就會拋出這個異常,最終聯(lián)網(wǎng)失敗。原因是:需要訪問到網(wǎng)絡(luò)必須要有權(quán)限,在AndroidManifest.xml中,需要進行如下配置:<uses-permissionandroid:name="android.permission.INTERNET"/>
如何使用Socket在客戶端實現(xiàn)長連接
長連接貌似是一個很高深莫測的知識,但是只要你做直播、IM、游戲、彈幕里面的任何一種,或者是你的app想要實時的接收某些消息,你就會要接觸到長連接技術(shù)。本文主要教你如何在客戶端如何使用Socket實現(xiàn)長連接。
Socket背景知識
要做長連接的話,是不能用http協(xié)議來做的,因為http協(xié)議已經(jīng)是應(yīng)用層協(xié)議了,并且http協(xié)議是無狀態(tài)的,而我們要做長連接,肯定是需要在應(yīng)用層封裝自己的業(yè)務(wù),所以就需要基于TCP協(xié)議來做,而基于TCP協(xié)議的話,就要用到Socket了。
Socket是java針對tcp層通信封裝的一套網(wǎng)絡(luò)方案
TCP協(xié)議我們知道,是基于ip(或者域名)和端口對指定機器進行的點對點訪問,他的連接成功有兩個條件,就是對方ip可以到達和端口是開放的
Socket能幫完成TCP三次握手,而應(yīng)用層的頭部信息需要自己去解析,也就是說,自己要制定好協(xié)議,并且要去解析byte
http也有長連接。在http1.0的時候,使用的是短連接,也就是說,每次請求一次數(shù)據(jù),都要重新建立連接。但是從http1.1之后,我們看到頭部會有一個
Connection:keep-alive
這個表示tcp連接建立之后不會馬上銷毀,而是保存一段時間,在這段時間內(nèi)如果需要請求改網(wǎng)站的其他數(shù)據(jù),都是使用這個連接來完成傳輸?shù)摹?/p>
Socket使用方式
Socket看上去不是很好用,因為他是基于java.io來實現(xiàn)的,你要直接跟InputStream和OutputStream打交道,也就是直接跟byte[]打交道,所以用起來并不是這么友好。
下面通過一個簡單的例子,往一臺服務(wù)器發(fā)\01\00\00\00\00這一串字節(jié),服務(wù)器也返回相同的字節(jié)流,上代碼:
@Test
publicvoidtestSocket()throwsException{
logger.debug("start");
Socketsocket=newSocket();
socket.connect(address);
byte[]output=newbyte[]{(byte)1,(byte)0,(byte)0,(byte)0,(byte)0};
socket.getOutputStream().write(output);
byte[]input=newbyte[64];
intreadByte=socket.getInputStream().read(input);
logger.debug("readByte"+readByte);
for(inti=0;i<readByte;i++){
logger.debug("read["+i+"]:"+input[i]);
}
socket.close();
}
輸出:
11:40:40.326[main]DEBUGcom.roy.test.SocketTest-start
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-readByte5
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-read1
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-read0
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-read0
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-read0
11:40:40.345[main]DEBUGcom.roy.test.SocketTest-read0
看出來寫起來還是比較麻煩的,主要就是InputStream,OutputStream和byte[]使用起來太不方便了。
SocketChannelblocking
Socket為了優(yōu)化自己的封裝和并發(fā)性能,推出了nio包下面的SocketChannel,這個相比于Socket的好處就是并發(fā)性能的提高和封裝的優(yōu)化了。
SocketChannel有兩種方式——阻塞和非阻塞的,阻塞的用法和Socket差不多,都是在read和write的時候會阻塞線程,下面用一段代碼來實現(xiàn)相同的功能。
@Test
publicvoidtestSocketChannelBlock()throwsException{
finalSocketChannelchannel=SocketChannel.open(address);
ByteBufferoutput=ByteBuffer.allocate(5);
output.put((byte)1);
output.putInt(0);
output.flip();
channel.write(output);
logger.debug("writecomplete,startread");
ByteBufferinput=ByteBuffer.allocate(5);
intreadByte=channel.read(input);
logger.debug("readByte"+readByte);
input.flip();
if(readByte==-1){
logger.debug("readByte==-1,return!");
return;
}
for(inti=0;i<readByte;i++){
logger.debug("read["+i+"]:"+input.get());
}
}
log輸出:
23:24:34.684[main]DEBUGcom.dz.test.SocketTest-writecomplete,startread
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-readByte5
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-read[0]:1
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-read[1]:0
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-read[2]:0
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-read[3]:0
23:24:34.901[main]DEBUGcom.dz.test.SocketTest-read[4]:0
從上面的。封裝優(yōu)化主要體現(xiàn)在ByteBuffer,IntBuffer這一系列類的封裝——因為是網(wǎng)絡(luò)相關(guān)的,所以這里用到的主要是ByteBuffer。
ByteBuffer和byte[]最大的區(qū)別,就是ByteBuffer可以很方便的讀取int,long等數(shù)據(jù)類型,他提供了getInt(),getInt(intoffset)這樣的方法,這種方法主要用在識別頭部數(shù)據(jù)部分,因為頭部數(shù)據(jù)一般都是由多種數(shù)據(jù)類型組成,比方說表示數(shù)據(jù)格式的contentType:String,表示長度的length:int等等,這些就是getInt()這樣的方法主要的應(yīng)用場景,而byte[]如果要取int,String相對來說就要復(fù)雜一些了,這是java.nio相比于java.io優(yōu)勢的一點。
這里需要說明一個比較坑的點,就是ByteBuffer.flip()這個方法,這個方法的作用主要是重置索引,在write()之前和read()之后調(diào)用,否則會因為索引不對,導致你的數(shù)據(jù)寫不進去,讀不出來。
ByteBuffer是一個功能強大的類,因為本文主要是講Socket和SocketChannel,所以在這里就不做過多描述。具體ByteBuffer的詳細介紹,可以參考:JavaNIO系列教程(三)Buffer
而nio相比于io最大的優(yōu)勢還是在于并發(fā)性能,因為nio里面的n代表的就是non-blocking的意思,上面那個讀取數(shù)據(jù)的代碼也相對老舊,一般我們?nèi)绻肧ocketChannel,都是用non-blocking的方式來實現(xiàn)的,而如果要用non-blocking模式,首先要介紹的就是Selector。
Selector
我們知道,傳統(tǒng)io是阻塞的,也就是說,一個線程只能處理一個io流,也就是一個Socket。有了Selector之后,一個線程就能處理多個SocketChannel。
Selector的原
OK,本文到此結(jié)束,希望對大家有所幫助。