?個(gè)人主頁:bit me??
?當(dāng)前專欄:Java EE初階??
??一. 網(wǎng)絡(luò)編程基礎(chǔ)
??1. 為什么需要網(wǎng)絡(luò)編程?
用戶在瀏覽器中,打開在線視頻網(wǎng)站,如優(yōu)酷看視頻,實(shí)質(zhì)是通過網(wǎng)絡(luò),獲取到網(wǎng)絡(luò)上的一個(gè)視頻資源。
與本地打開視頻文件類似,只是視頻文件這個(gè)資源的來源是網(wǎng)絡(luò)。
相比本地資源來說,網(wǎng)絡(luò)提供了更為豐富的網(wǎng)絡(luò)資源:
所謂的網(wǎng)絡(luò)資源,其實(shí)就是在網(wǎng)絡(luò)中可以獲取的各種數(shù)據(jù)資源。
而所有的網(wǎng)絡(luò)資源,都是通過網(wǎng)絡(luò)編程來進(jìn)行數(shù)據(jù)傳輸?shù)摹?/p>
??2. 什么是網(wǎng)絡(luò)編程
網(wǎng)絡(luò)編程,指網(wǎng)絡(luò)上的主機(jī),通過不同的進(jìn)程,以編程的方式實(shí)現(xiàn)網(wǎng)絡(luò)通信(或稱為網(wǎng)絡(luò)數(shù)據(jù)傳輸)。
當(dāng)然,我們只要滿足進(jìn)程不同就行;所以即便是同一個(gè)主機(jī),只要是不同進(jìn)程,基于網(wǎng)絡(luò)來傳輸數(shù)據(jù),也屬于網(wǎng)絡(luò)編程。
特殊的,對(duì)于開發(fā)來說,在條件有限的情況下,一般也都是在一個(gè)主機(jī)中運(yùn)行多個(gè)進(jìn)程來完成網(wǎng)絡(luò)編程。
但是,我們一定要明確,我們的目的是提供網(wǎng)絡(luò)上不同主機(jī),基于網(wǎng)絡(luò)來傳輸數(shù)據(jù)資源:
- 進(jìn)程A:編程來獲取網(wǎng)絡(luò)資源
- 進(jìn)程B:編程來提供網(wǎng)絡(luò)資源
??3. 網(wǎng)絡(luò)編程中的基礎(chǔ)概念
- 網(wǎng)絡(luò)編程:寫代碼,實(shí)現(xiàn)兩個(gè) / 多個(gè)進(jìn)程,通過網(wǎng)絡(luò),來進(jìn)行相互通信。
由于進(jìn)程具有隔離性(每個(gè)進(jìn)程都有自己獨(dú)立的虛擬空間地址),進(jìn)程間通信,借助一個(gè)每個(gè)進(jìn)程都能訪問到的公共區(qū)域,完成數(shù)據(jù)交換。
網(wǎng)絡(luò)編程,也就是一種進(jìn)程間通信的方式,借助公共的區(qū)域,就是網(wǎng)卡(當(dāng)下最主流的方式,既能讓同一個(gè)主機(jī)的多個(gè)進(jìn)程間通信,也可以讓不同主機(jī)的多個(gè)進(jìn)程間通信),尤其是對(duì)于高并發(fā),分布式,大數(shù)據(jù)這樣的時(shí)代有影響。
- 客戶端(client) / 服務(wù)器(server)
客戶端:主動(dòng)發(fā)送網(wǎng)絡(luò)數(shù)據(jù)的一方
服務(wù)器:被動(dòng)接受網(wǎng)絡(luò)數(shù)據(jù)的一方
因?yàn)榉?wù)器無法知道客戶端啥時(shí)候發(fā)來數(shù)據(jù),因此就只能長時(shí)間運(yùn)行,甚至 7 * 24 小時(shí)運(yùn)行。
- 請(qǐng)求(request) / 響應(yīng)(response)
請(qǐng)求:客戶端給服務(wù)器發(fā)送的數(shù)據(jù)
響應(yīng):服務(wù)器給客戶端返回的數(shù)據(jù)
- 客戶端和服務(wù)器之間的交互方式
- 一問一答(最常見的方式,比如瀏覽網(wǎng)頁)
客戶端給服務(wù)器發(fā)個(gè)請(qǐng)求,服務(wù)器給客戶端返回個(gè)響應(yīng)
- 多問一答(更少見一些,比如上傳文件)
客戶端發(fā)多個(gè)請(qǐng)求,服務(wù)器響應(yīng)一個(gè)
- 一問多答(還行,比如下載文件)
客戶端發(fā)一個(gè)請(qǐng)求,服務(wù)器返回多個(gè)響應(yīng)
- 多問多答(遠(yuǎn)程控制,游戲串流…)
客戶端發(fā)送多個(gè)請(qǐng)求,服務(wù)器返回多個(gè)響應(yīng)
??二. Socket套接字
進(jìn)行網(wǎng)絡(luò)編程,需要使用 操作系統(tǒng) 提供的 網(wǎng)絡(luò)編程 API
網(wǎng)絡(luò)編程在應(yīng)用層進(jìn)行,就需要調(diào)用傳輸層,正是這個(gè)傳輸層,提供了 “網(wǎng)絡(luò)通信 api” ,這些 api 也叫做 socket api 。(操作系統(tǒng)提供的原生 api ,是 C 語言的。JVM 非常貼心把 C 風(fēng)格的 api 封裝了一下,變成 Java 中的面向?qū)ο箫L(fēng)格的 api)
Socket套接字,是由系統(tǒng)提供用于網(wǎng)絡(luò)通信的技術(shù),是基于TCP/IP協(xié)議的網(wǎng)絡(luò)通信的基本操作單元?;赟ocket套接字的網(wǎng)絡(luò)程序開發(fā)就是網(wǎng)絡(luò)編程。
傳輸層提供了兩個(gè)非常重要的協(xié)議:TCP / UDP。他們截然不同,這兩個(gè)協(xié)議對(duì)應(yīng)的 socket api 也是截然不同的。
流套接字:使用傳輸層TCP協(xié)議
TCP,即Transmission Control Protocol(傳輸控制協(xié)議),傳輸層協(xié)議。
以下為TCP的特點(diǎn)(細(xì)節(jié)后續(xù)再講):
- 有連接
- 可靠傳輸
- 面向字節(jié)流
- 全雙工
對(duì)于字節(jié)流來說,可以簡單的理解為,傳輸數(shù)據(jù)是基于IO流,流式數(shù)據(jù)的特征就是在IO流沒有關(guān)閉的情況下,是無邊界的數(shù)據(jù),可以多次發(fā)送,也可以分開多次接收。
數(shù)據(jù)報(bào)套接字:使用傳輸層UDP協(xié)議
UDP,即User Datagram Protocol(用戶數(shù)據(jù)報(bào)協(xié)議),傳輸層協(xié)議。
以下為UDP的特點(diǎn)(細(xì)節(jié)后續(xù)再講):
- 無連接
- 不可靠傳輸
- 面向數(shù)據(jù)報(bào)
- 全雙工
對(duì)于數(shù)據(jù)報(bào)來說,可以簡單的理解為,傳輸數(shù)據(jù)是一塊一塊的,發(fā)送一塊數(shù)據(jù)假如100個(gè)字節(jié),必須一次發(fā)送,接收也必須一次接收100個(gè)字節(jié),而不能分100次,每次接收1個(gè)字節(jié)。
原始套接字(了解即可):
原始套接字用于自定義傳輸層協(xié)議,用于讀寫內(nèi)核沒有處理的IP協(xié)議數(shù)據(jù)。
- 有連接:打電話,先建立連接,然后再通信
- 無連接:發(fā)微信,不必建立連接,直接通信即可
- 可靠傳輸:數(shù)據(jù)對(duì)方收沒收到,發(fā)送方能夠有感知(打電話)
- 不可靠傳輸:數(shù)據(jù)對(duì)方收沒收到,也不管,也不知道(發(fā)微信)
?
網(wǎng)絡(luò)通信是無法保證 100% 到達(dá)的(網(wǎng)線被挖掘機(jī)挖斷)
- 面向字節(jié)流:這里的字節(jié)流和文件那里的字節(jié)流是一樣的(不光概念一樣,連代碼編寫都是一樣的)
- 面向數(shù)據(jù)報(bào):以數(shù)據(jù)報(bào)為傳輸?shù)幕締挝?/font>
- 全雙工:雙向通信,一個(gè)管道,能 A->B,B->A 同時(shí)進(jìn)行
- 半雙工:單向通信,一個(gè)管道,同一時(shí)刻,要么 A->B,要么 B->A ,不能同時(shí)進(jìn)行。
??三. Socket編程注意事項(xiàng)
- 客戶端和服務(wù)端:開發(fā)時(shí),經(jīng)常是基于一個(gè)主機(jī)開啟兩個(gè)進(jìn)程作為客戶端和服務(wù)端,但真實(shí)的場景,一般都是不同主機(jī)。
- 注意目的IP和目的端口號(hào),標(biāo)識(shí)了一次數(shù)據(jù)傳輸時(shí)要發(fā)送數(shù)據(jù)的終點(diǎn)主機(jī)和進(jìn)程
- Socket編程我們是使用流套接字和數(shù)據(jù)報(bào)套接字,基于傳輸層的TCP或UDP協(xié)議,但應(yīng)用層協(xié)議,也需要考慮,這塊我們在后續(xù)來說明如何設(shè)計(jì)應(yīng)用層協(xié)議。
- 關(guān)于端口被占用的問題
如果一個(gè)進(jìn)程A已經(jīng)綁定了一個(gè)端口,再啟動(dòng)一個(gè)進(jìn)程B綁定該端口,就會(huì)報(bào)錯(cuò),這種情況也叫端
口被占用。對(duì)于java進(jìn)程來說,端口被占用的常見報(bào)錯(cuò)信息如下:
此時(shí)需要檢查進(jìn)程B綁定的是哪個(gè)端口,再查看該端口被哪個(gè)進(jìn)程占用。以下為通過端口號(hào)查進(jìn)程
的方式:
-
在cmd輸入 netstat -ano | findstr 端口號(hào) ,則可以顯示對(duì)應(yīng)進(jìn)程的pid。
-
在任務(wù)管理器中,通過pid查找進(jìn)程文章來源:http://www.zghlxwxcb.cn/news/detail-414017.html
解決端口被占用的問題:文章來源地址http://www.zghlxwxcb.cn/news/detail-414017.html
- 如果占用端口的進(jìn)程A不需要運(yùn)行,就可以關(guān)閉A后,再啟動(dòng)需要綁定該端口的進(jìn)程B
- 如果需要運(yùn)行A進(jìn)程,則可以修改進(jìn)程B的綁定端口,換為其他沒有使用的端口。
到了這里,關(guān)于【網(wǎng)絡(luò)編程】網(wǎng)絡(luò)編程 和 Socket 套接字認(rèn)識(shí)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!