????01-網(wǎng)絡(luò)編程(TCP-上傳圖片)
? ? ? ? 我們看看客戶端和服務(wù)端都需要做哪些事情~
? ? ? ? 客戶端:
? ? ? ? 1,服務(wù)端點(diǎn)豌熄。
? ? ? ? 2包晰,讀取客戶端已有的圖片數(shù)據(jù)。
? ? ? ? 3椎侠,通過socket輸出流將數(shù)據(jù)發(fā)給服務(wù)端。
? ? ? ? 4措拇,讀取服務(wù)端反饋信息我纪。
? ? ? ? 5,關(guān)閉。
? ? ? ? 代碼:?
? ? ? ? 這段代碼有一個(gè)小小的bug浅悉,我們需要加上一句:
? ? ? ? 服務(wù)端:?
? ? ? ? 別忘了頭文件哦:
? ? ? ? 運(yùn)行結(jié)果:
????02-網(wǎng)絡(luò)編程(TCP-客戶端并發(fā)上傳圖片)
????????上節(jié)的代碼中趟据,服務(wù)端有局限性。當(dāng)A客戶端連接上以后仇冯,被服務(wù)端獲取到之宿,服務(wù)端執(zhí)行具體流程,這時(shí)B客戶端連接的話苛坚,只有等待比被。因?yàn)榉?wù)端還沒有處理完A客戶端的請(qǐng)求,還沒有循環(huán)回來執(zhí)行下次accept方法泼舱,所以暫時(shí)獲取不到B客戶端對(duì)象等缀。
? ? ? ? 那么為了可以讓多個(gè)客戶端同時(shí)并發(fā)訪問服務(wù)端,那么服務(wù)端最好就是將每個(gè)客戶端封裝到一個(gè)單獨(dú)的線程中娇昙,這樣尺迂,就可以同時(shí)處理多個(gè)客戶端請(qǐng)求。
? ? ? ? 如何定義線程呢冒掌?
? ? ? ? 只要明確了每一個(gè)客戶端要在服務(wù)端執(zhí)行的代碼即可噪裕,將該代碼存入run方法中。
? ? ? ? 代碼:
? ? ? ? 運(yùn)行:
? ? ? ? 可以接著上傳股毫,但是發(fā)現(xiàn)將前一個(gè)上傳的文件覆蓋了膳音。
? ? ? ? 我們不希望它被覆蓋掉,所以需要修改一下代碼铃诬,給它定義一個(gè)不會(huì)重復(fù)的命名方式~
? ? ? ? 代碼:?
? ? ? ? 運(yùn)行結(jié)果:
? ? ? ? OK祭陷,服務(wù)端的這個(gè)小問題解決了。
? ? ? ? 客戶端我們還需要做一些改動(dòng)趣席。
? ? ? ? 運(yùn)行效果:
????03-網(wǎng)絡(luò)編程(TCP-客戶端并發(fā)登錄)
? ? ? ? 需求:
? ? ? ? 我們?cè)趗ser.txt這個(gè)文件中存入了用戶名:
? ? ? ? 代碼:??
? ? ? ? 剛剛循環(huán)部分的語句還不夠完善兵志,我們將它完善一下:
? ? ? ? 好,繼續(xù):
? ? ? ? 運(yùn)行:
? ? ? ? 超過三次后就不行了哦:
????04-網(wǎng)絡(luò)編程(瀏覽器客戶端-自定義服務(wù)端)
? ? ? ? 我們已經(jīng)寫了那么多客戶端宣肚、服務(wù)端的程序想罕,我們發(fā)現(xiàn),客戶端霉涨、服務(wù)端無非就是基于網(wǎng)絡(luò)應(yīng)用的程序而已弧呐。像這樣的程序,在我們現(xiàn)實(shí)生活中很多嵌纲,比如瀏覽器就是標(biāo)準(zhǔn)的客戶端。我們現(xiàn)在既能做客戶端腥沽,又能做服務(wù)端逮走,那我們能不能做一個(gè)服務(wù)端,讓瀏覽器來訪問呢今阳?
? ? ? ? 接下來就演示一下客戶端和服務(wù)端师溅,客戶端:瀏覽器茅信,服務(wù)端:自定義。
? ? ? ? 代碼:
? ? ? ? 運(yùn)行效果:
? ? ? ? 我們看到墓臭,瀏覽器收到了自己服務(wù)端發(fā)來的數(shù)據(jù)蘸鲸。
? ? ? ? 其實(shí),瀏覽器在向外發(fā)請(qǐng)求窿锉,它將這些請(qǐng)求發(fā)送到了某些主機(jī)的11000端口上了酌摇,這些端口接收到請(qǐng)求,就返回?cái)?shù)據(jù)“客戶端你好”嗡载,這些數(shù)據(jù)瀏覽器能夠解析窑多。
? ? ? ? 瀏覽器可厲害了呢,不光能夠解析這個(gè)數(shù)據(jù)洼滚,還能夠解析其他的呢:?
? ? ? ? 看看效果:
????????這些數(shù)據(jù)都被瀏覽器解析啦埂息。
? ? ? ? 客戶端除了瀏覽器還有其他的~
? ? ? ? 我們?cè)僭囈幌拢匦聠?dòng)一次服務(wù)端:
? ? ? ? 再重新打開一個(gè)命令行面板遥巴,輸入:
? ? ? ? 它也收到了數(shù)據(jù):
? ? ? ? 介紹一下telnet千康,它是windows當(dāng)中為我們提供的遠(yuǎn)程登錄的工具,它可以去連接網(wǎng)絡(luò)中的任意一臺(tái)主機(jī)铲掐,在dos命令行下連接拾弃,連接完以后可以對(duì)這臺(tái)主機(jī)進(jìn)行命令式的配置。比如說玩網(wǎng)絡(luò)的時(shí)候迹炼,里面有很多交換機(jī)和路由器砸彬,這些設(shè)備都是可以配置的,我們可以通過telnet命令連接過去斯入,遠(yuǎn)程登錄過去砂碉,這樣我們本地就可以接收到路由器的配置。簡(jiǎn)言之刻两,telnet可以理解為一個(gè)客戶端軟件增蹭。
????05-網(wǎng)絡(luò)編程(瀏覽器客戶端-Tomcat服務(wù)端)
? ? ? ? 這節(jié)課我們來演示:
? ? ? ? 客戶端:瀏覽器。
? ? ? ? 服務(wù)端:Tomcat服務(wù)器磅摹。
? ? ? ? Tomcat我們沒學(xué)過滋迈,但是它就是一個(gè)服務(wù)器軟件,學(xué)沒學(xué)過不重要户誓。
? ? ? ? 它能提供服務(wù)饼灿,說明了里面封裝了Server Socket,事實(shí)上它就是純Java編寫的軟件帝美,里面封裝著Server Socket碍彭。
? ? ? ? 我們雙擊startup.bat啟動(dòng),發(fā)現(xiàn)服務(wù)器用的是8080端口:
? ? ? ? Tomcat有個(gè)好處就是,可以讀取我們自定義的資源庇忌。
? ? ? ? 我們建立一個(gè)自己的網(wǎng)站舞箍,myweb,在其中寫一個(gè)網(wǎng)頁demo.html:
? ? ? ? 訪問:
????06-網(wǎng)絡(luò)編程(自定義瀏覽器-Tomcat服務(wù)端)
? ? ? ? 上節(jié)課我們演示了瀏覽器和Tomcat服務(wù)器的特點(diǎn)皆疹,那么疏橄,我們已經(jīng)學(xué)會(huì)了客戶端服務(wù)端以后,我們能不能模擬瀏覽器的動(dòng)作略就,像瀏覽器一樣到Tomcat服務(wù)端去請(qǐng)求數(shù)據(jù)捎迫?
? ? ? ? 這時(shí)我們需要了解一下,瀏覽器在訪問服務(wù)器的時(shí)候它發(fā)了什么數(shù)據(jù)残制,才能請(qǐng)求到服務(wù)器的資源立砸。
? ? ? ? 運(yùn)行:
? ? ? ? 訪問11000端口:
? ? ? ? 我們發(fā)現(xiàn),瀏覽器給服務(wù)端發(fā)送了一個(gè)消息:
? ? ? ? 這些就是HTTP的請(qǐng)求消息頭初茶。
? ? ? ? 瀏覽器和Tomcat雖然都是不同廠商制作的客戶端和服務(wù)端颗祝,但是呢,它們都遵從了一些國際標(biāo)準(zhǔn)化的協(xié)議和規(guī)則恼布。底層的傳輸規(guī)則都走的是TCP螺戳,應(yīng)用層的協(xié)議HTTP是一個(gè)公共的傳輸規(guī)則。那么折汞,瀏覽器廠商要想和不同的廠商進(jìn)行數(shù)據(jù)的交互倔幼,他們都得先遵從這個(gè)規(guī)則才可以。
? ? ? ? 它是什么意思呢爽待?我們來解釋一下(為了解釋更多內(nèi)容损同,我們將GET后面的內(nèi)容替換成了內(nèi)容更多的情況):
? ? ? ? 瀏覽器首先向服務(wù)器發(fā)送了一個(gè)GET請(qǐng)求,這個(gè)GET請(qǐng)求是一種請(qǐng)求方式鸟款,它有自己的特點(diǎn)膏燃。它緊接著跟服務(wù)器說,
? ? ? ? “我想要訪問myweb/demo.html這個(gè)資源何什,我的協(xié)議是HTTP组哩,版本是1.1〈υ”
????????? “嘿伶贰!服務(wù)器!雖然咱倆不是一個(gè)公司罐栈,但是我告訴你哦黍衙,咱們倆遵從同一個(gè)標(biāo)準(zhǔn)的協(xié)議/規(guī)則,我可以接收的數(shù)據(jù)有:flash荠诬、gif琅翻、......涯捻、QVOD⊥”
?????????“我的語言是簡(jiǎn)體中文版。 ”
? ???????“我的壓縮方式是gzip凌外”缱穑”
? ???????一些用戶信息:
? ???????“我要訪問的是192.168.1.254這臺(tái)主機(jī)的11000端口】导”
????????連接:保持活動(dòng)摄欲。?
? ? ? ? OK,內(nèi)容解釋完了疮薇,下面來一個(gè)比較全的地址的解釋:
????????“我要訪問192.168.1.254這臺(tái)主機(jī)的11000端口下的myweb這個(gè)資源路徑下的demo.html這個(gè)資源”
? ? ? ? 注意一下胸墙,請(qǐng)求數(shù)據(jù)頭和請(qǐng)求數(shù)據(jù)體之間必定有一個(gè)空行隔開(這個(gè)是格式定義的標(biāo)準(zhǔn),識(shí)別到空行后就表示前面的數(shù)據(jù)頭結(jié)束了):
? ? ? ? 好了按咒,瀏覽器發(fā)什么我們都知道了迟隅,接下來我們自定義一個(gè)客戶端。
? ? ? ? 接下來演示:
? ? ? ? 客戶端:自定義励七。
? ? ? ? 服務(wù)端:Tomcat服務(wù)器智袭。
? ? ? ? 代碼:
? ? ? ? 我們先用自己的瀏覽器客戶端走一遍:
? ? ? ? 接下來用自己的客戶端來試一下:
? ? ? ? 但是運(yùn)行的時(shí)間有點(diǎn)長,怎么辦呢掠抬?
? ? ? ? 我們修改一下Connection屬性的內(nèi)容:
? ? ? ? Keep-Alive是保持連接吼野,數(shù)據(jù)發(fā)送完了之后還在,一直在等著两波,而closed則是發(fā)完數(shù)據(jù)后就斷開連接了瞳步。
? ? ? ? 這個(gè)不是很重要,我們看一下這次的消息頭腰奋,和上次的不太一樣单起,這個(gè)叫做HTTP應(yīng)答消息頭,是Tomcat服務(wù)器發(fā)過來的氛堕。
? ? ? ? 其中馏臭,200是響應(yīng)狀態(tài)碼,代表成功讼稚,OK是200的描述信息括儒。另外的信息有:Server是阿帕奇的、最后一次被修改的時(shí)間锐想、文本類型帮寻、文本長度、時(shí)間赠摇、連接狀態(tài)固逗。
????07-網(wǎng)絡(luò)編程(自定義圖形界面瀏覽器-Tomcat服務(wù)端)
????????剛剛我們已經(jīng)做出了dos命令行浅蚪,接下來是不是可以做一下圖像界面呀?? ? ? ??
? ? ? ? 運(yùn)行:
? ? ? ? 這只是圖形化界面烫罩,接下來我們要實(shí)現(xiàn)它的功能惜傲,在第一個(gè)對(duì)話框中輸入地址,點(diǎn)擊“轉(zhuǎn)到”贝攒,可以轉(zhuǎn)到相應(yīng)的地址頁面盗誊。實(shí)現(xiàn)方式就是要對(duì)地址進(jìn)行字符串的分割,得到主機(jī)名隘弊、端口哈踱、資源路徑、資源名等信息梨熙。
? ? ? ? 接下來我們對(duì)代碼進(jìn)行修改开镣,將showDir這個(gè)函數(shù)中的代碼全都刪掉,我們重新寫咽扇,先試著對(duì)地址進(jìn)行字符串分割:
? ? ? ? 運(yùn)行效果:
? ? ? ? 我們?cè)龠M(jìn)一步將主機(jī)名和端口號(hào)分割開:
? ? ? ? 接下來將之前的代碼復(fù)制過來:
? ? ? ? 接上面藍(lán)框中的:
? ? ? ? 對(duì)tf.addKeyListener事件和but.addActionListener事件進(jìn)行修改:
? ? ? ? 再導(dǎo)入這個(gè)包:?
? ? ? ? 但是運(yùn)行出現(xiàn)了一些小問題邪财,我們發(fā)現(xiàn)剛剛代碼中有些需要修改的地方,在showDir這個(gè)函數(shù)中肌割,1卧蜓,加入清空動(dòng)作:
? ? ? ? 2,將下面這句話注釋掉:
? ? ? ? 3把敞,在消息頭后添加空行:
? ? ? ? 運(yùn)行效果:
? ? ? ? 我們獲取到了數(shù)據(jù)弥奸,只是解析不了里面的html代碼。
? ? ? ? 瀏覽器強(qiáng)大就強(qiáng)大在它里面掛了n多的解析引擎奋早,比如html解析引擎盛霎、cs解析引擎、javascript解析引擎耽装,etc愤炸。
? ? ? ? 另一個(gè)問題就是,瀏覽器顯示的數(shù)據(jù)只有html文檔里的掉奄,而我們將響應(yīng)頭的信息也顯示了规个。
? ? ? ? 瀏覽器是應(yīng)用層的軟件,我們做的這個(gè)軟件走的是傳輸層姓建,我們將傳輸層發(fā)過來的數(shù)據(jù)全拿過來了诞仓,而瀏覽器把有關(guān)于HTTP協(xié)議封裝的信息拆掉了。我們知道速兔,數(shù)據(jù)在向上傳輸?shù)綉?yīng)用層的時(shí)候會(huì)拆包墅拭,它把這個(gè)包拆了,我們沒拆了涣狗。下節(jié)課我們就要把它拆掉!
????08-網(wǎng)絡(luò)編程(URL-URLConnection)
? ? ? ? 我們來看一下URL這個(gè)類:? ??
? ? ? ? 寫一個(gè)URL地址谍婉,可以把它封裝成對(duì)象:
? ? ? ? 下面我們演示一下URL對(duì)象舒憾,主要是試一下以下幾個(gè)方法:
? ? ? ? 代碼:
? ? ? ? 運(yùn)行:
? ? ? ? 為什么getPath和getFile結(jié)果一樣呢?而getQuery為null又是什么意思呢穗熬?
? ? ? ? 我們知道地址后面往往都會(huì)有些參數(shù)信息镀迂,比如這樣:
? ? ? ? OK,添加了參數(shù)信息之后我們?cè)龠\(yùn)行一下:
? ? ? ? 我們發(fā)現(xiàn)唤蔗,getFile是帶著參數(shù)信息的地址招拙,getQuery拿到的則是參數(shù)信息。
? ? ? ? 我們平時(shí)在上網(wǎng)的時(shí)候輸入的網(wǎng)址里都不會(huì)寫端口的措译,所以我們將剛剛地址中的端口號(hào)刪掉:
? ? ? ? 重新運(yùn)行,當(dāng)沒有指定端口的時(shí)候饰序,這個(gè)端口返回的就是-1:
? ? ? ? 下面講一個(gè)我們必須要掌握的對(duì)象领虹。
? ? ? ? 只要調(diào)用openConnection方法,就會(huì)去連接這臺(tái)主機(jī)求豫,獲取主機(jī)的連接對(duì)象塌衰。
? ? ? ? 我們?cè)囍B接并打印一下返回的對(duì)象,打印結(jié)果中蝠嘉,顯示了它對(duì)應(yīng)的是http協(xié)議下的URL連接最疆,目的地址也有:
? ? ? ? 好,現(xiàn)在連接到目的地址了蚤告,我們就可以將它的數(shù)據(jù)拿回來了努酸。
? ? ? ? 代碼:
? ? ? ? 運(yùn)行,我們發(fā)現(xiàn)它沒有響應(yīng)頭:
? ? ? ? 因?yàn)槲覀冏叩牟辉偈莻鬏攲佣徘。菓?yīng)用層获诈,應(yīng)用層的http協(xié)議,把http協(xié)議所識(shí)別到的東西去掉了心褐,返回了數(shù)據(jù)主體舔涎。?
? ? ? ? 現(xiàn)在我們將剛剛的方法用到之前寫的模擬瀏覽器可視化界面中,找到之前的代碼逗爹,找到代碼中showDir這個(gè)函數(shù)亡嫌,只保留前兩行代碼,后面的都刪掉:
? ? ? ? 記得將url改成urlPath掘而,避免重名挟冠,后面寫入我們這節(jié)課的新方法:
? ? ? ? 運(yùn)行,發(fā)現(xiàn)響應(yīng)頭被拆掉啦:
? ? ? ? 都這里镣屹,除了有點(diǎn)遺憾不能進(jìn)行解析圃郊,其他都沒有問題。
? ? ? ? URL中除了有openConnection方法女蜈,還有openStream方法持舆,它可以直接開流:
? ? ? ? 我們看到其實(shí)它是兩個(gè)步驟的縮寫色瘩,所以用哪個(gè)都可以啦:
????09-網(wǎng)絡(luò)編程(小知識(shí)點(diǎn))
? ? ? ? 我們?cè)谶M(jìn)行Socket對(duì)象的建立的時(shí)候,有一個(gè)不需要傳遞參數(shù)的空參數(shù)方法:
? ? ? ? 可是沒有傳入主機(jī)的話逸寓,它該連哪一個(gè)呢居兆?
? ? ? ? 這個(gè)時(shí)候就會(huì)用connect方法去連接:
? ? ? ? 我們看看SocketAddress這個(gè)對(duì)象,發(fā)現(xiàn)它是一個(gè)抽象類:
? ? ? ? 我們看一下它的子類InetSocketAddress竹伸,發(fā)現(xiàn)它封裝的是IP地址和端口:
? ? ? ? 下面再說說ServerSocket這個(gè)比較特殊的部分:
? ? ? ? 我們可以看到它的構(gòu)造方法有:
? ? ? ? 其中有個(gè)參數(shù)叫backlog,它是什么意思呢勋篓?
? ? ? ? 點(diǎn)進(jìn)去看看:
? ? ? ? 那么吧享,隊(duì)列的最大長度是什么意思呢?
? ? ? ? 它指的是譬嚣,能同時(shí)連接到服務(wù)器的客戶端的最大個(gè)數(shù)钢颂。
????10-網(wǎng)絡(luò)編程(域名解析)
? ? ? ? 接下來講點(diǎn)比較重點(diǎn)的網(wǎng)絡(luò)知識(shí):我們?cè)跒g覽器中輸入某一個(gè)網(wǎng)址訪問某一臺(tái)主機(jī)的時(shí)候,它到底做了什么事情拜银?
? ? ? ? 注意殊鞭,這個(gè)必須要掌握喔。
? ? ? ? 我們知道尼桶,一般的網(wǎng)址并不是直接的ip地址操灿,所以我們需要將它翻譯成ip地址,也就是域名解析泵督,這個(gè)時(shí)候要用到DNS服務(wù)器趾盐。
? ? ? ? 在這個(gè)面板中可以進(jìn)行DNS服務(wù)器的配置:
? ??????這里的DNS服務(wù)器可以不配置,使用默認(rèn)的小腊,則是默認(rèn)的電信/聯(lián)通的服務(wù)器谤碳,當(dāng)然也可以自己手動(dòng)配置,但是如果我們?cè)谥袊渲靡粋€(gè)美國的DNS服務(wù)器溢豆,就太遠(yuǎn)了蜒简,可能在請(qǐng)求的這個(gè)過程中時(shí)間過長超時(shí)了。
? ? ? ? 接著講下一個(gè)知識(shí)點(diǎn)漩仙,如下圖搓茬,這兩種方式都可以訪問到目標(biāo)頁面:
? ? ? ? 因?yàn)?27.0.0.1和localhost是有影射關(guān)系的,這個(gè)映射關(guān)系就在本機(jī)上队他,路徑如上圖卷仑,我們找到這個(gè)hosts文件:
? ? ? ? 哈哈,這里還有很多其他域名的映射麸折,因?yàn)樗鼈兌际遣《揪W(wǎng)站锡凝,我們都映射到自己制定的ip地址上就不會(huì)被坑啦!
? ? ? ? 接下來我們玩一下垢啼,將localhost修改成myhost:
? ? ? ? 這時(shí)用myhost訪問窜锯,成功:
? ? ? ? 一個(gè)地址可以起多個(gè)名字张肾,我們?cè)倨ひ幌拢?/p>
? ? ? ? 同樣也成功:
? ? ? ? 接下來劃重點(diǎn):當(dāng)我們?cè)谌ピL問主機(jī)的時(shí)候,其實(shí)它先找的是本地锚扎,本地沒有才去外面找吞瞪。
? ? ? ? 我們?nèi)绻佬吕说膇p地址,并且把它寫在host文件中驾孔,它就能直接在本地找到芍秆,就不用走DNS服務(wù)器了,相對(duì)而言提高了速度翠勉。
? ? ? ? 解析成功后妖啥,先看是什么協(xié)議,然后啟動(dòng)相應(yīng)的協(xié)議对碌,去解析后面的主機(jī)和端口迹栓,etc。
? ? ? ? 這是倒數(shù)第二天的課程了俭缓,還有最后一天等著你,加油酥郭,小楠楠~