1、tcp和udp的區別 1
2、tcp連接建立的時候3次握手,斷開連接的4次握手的具體過程 1
3、什么是同步?什么是異步? 2
4、.什么是阻塞?什么是非阻塞? 5
5、什么是阻塞IO?什么是非阻塞IO? 6
6、什么是同步IO?什么是異步IO? 7
7、 IO模型有幾種?分別是什么? 8
8、 Reactor和Proactor IO設計模式是什么? 13
9、Java NIO 中的Buffer是什么?如何使用? 16
10、Nio buffer 的內部結構是什么? 17
11、Java NIO 中的 Channel是什么?有什么特點? 18
12、Java NIO中的Selector是什么? 21
13、簡單講一下文件IO中的Path和Files 22
14、select、poll和epoll的區別 23
15、網絡編程中設計並發服務器,使用多進程 與 多線程 ,請問有什么區別? 29
15、網絡編程的一般步驟 29
16、TCP的全稱是? 31
17、UDP的全稱是? 31
18、請說出TCP和UDP的區別? 31
19、TCP為什么不是兩次連接?而是三次握手? 33
20、說明socket是什么? 34
21、為什么需要端口?端口是真實存在的還是虛擬的概念? 35
22、Java中,端口使用兩個字節表示,可以表示多少個端口? UDP和TCP端口是各自獨立的嗎? 35
23、URL類有什么作用? 35
24、基於TCP的Socket網絡編程的主要步驟是什么? 36
25、【上機】寫出建立TCP服務器ServerSocket的代碼。並說明accept方法有什么特點? 37
26、【上機】寫出建立TCP客戶端Socket的代碼。並說明建立Socket后,通過什么方法Socket獲得流對象? 37
27、基於UDP的Socket網絡編程的主要步驟是什么? 37
28、【上機】使用UDP的方式,完成對象的傳遞。 38
29、HTTPClient相關問題 39
30、NIO 和傳統 BIO區別是什么? 40
31、Java NIO 的幾個核心組成部分是什么?作用分別是什么? 41
32、簡單說一下http協議? 47
33、http協議下客戶端請求報文是什么? 48
34、描述一下http協議服務器響應報文有哪些? 49
35、HTTP協議中常用的請求方法有哪些 50
36、常見的HTTP狀態碼有哪些 51
37、HTTP 協議中content-type指的是什么? 55
38、網絡傳輸協議本質和作用是什么? 65
39、可以實現一個簡單的網絡協議嗎? 65
1、tcp和udp的區別
TCP:是面向連接的流傳輸控制協議,具有高可靠性,確保傳輸數據的正確性,有驗證重發機制,因此不會出現丟失或亂序。
UDP:是無連接的數據報服務,不對數據報進行檢查與修改,無須等待對方的應答,會出現分組丟失、重復、亂序,但具有較好的實時性,UDP段結構比TCP的段結構簡單,因此網絡開銷也小。
2、tcp連接建立的時候3次握手,斷開連接的4次握手的具體過程
- 建立連接采用的3次握手協議,具體是指:
l 第一次握手是客戶端connect連接到server
l 第二次server accept client的請求之后,向client端發送一個消息,相當於說我都准備好了,你連接上我了
l 第三次 就是client向server發送的,就是對第二次握手消息的確認。之后client和server就開始通訊了。
2.斷開連接的4次握手,具體如下:
l 斷開連接的一端發送close請求是第一次握手
l 另外一端接收到斷開連接的請求之后需要對close進行確認,發送一個消息,這是第二次握手
l 發送了確認消息之后還要向對端發送close消息,要關閉對對端的連接,這是第3次握手
l 而在最初發送斷開連接的一端接收到消息之后,進入到一個很重要的狀態time_wait狀態,這個狀態也是面試官經常問道的問題,最后一次握手是最初發送斷開連接的一端接收到消息之后。對消息的確認。
3、什么是同步?什么是異步?
同步:
如果有多個任務或者事件要發生,這些任務或者事件必須逐個地進行,一個事件或者任務的執行會導致整個流程的暫時等待,這些事件沒有辦法並發地執行;
異步:
如果有多個任務或者事件發生,這些事件可以並發地執行,一個事件或者任務的執行不會導致整個流程的暫時等待。
這就是同步和異步。
舉個簡單的例子,假如有一個任務包括兩個子任務A和B,對於同步來說,當A在執行的過程中,B只有等待,直至A執行完畢,B才能執行;而對於異步就是A和B可以並發地執行,B不必等待A執行完畢之后再執行,這樣就不會由於A的執行導致整個任務的暫時等待。
如果還不理解,可以先看下面這2段代碼:
void fun1() {
}
void fun2() {
}
void function(){
fun1();
fun2()
.....
.....
}
這段代碼就是典型的同步,在方法function中,fun1在執行的過程中會導致后續的fun2無法執行,fun2必須等待fun1執行完畢才可以執行。
接着看下面這段代碼:
void fun1() {
}
void fun2() {
}
void function(){
new Thread(){
public void run() {
fun1();
}
}.start();
new Thread(){
public void run() {
fun2();
}
}.start();
.....
.....
}
這段代碼是一種典型的異步,fun1的執行不會影響到fun2的執行,並且fun1和fun2的執行不會導致其后續的執行過程處於暫時的等待。
事實上,同步和異步是一個非常廣的概念,它們的重點在於多個任務和事件發生時,一個事件的發生或執行是否會導致整個流程的暫時等待。我覺得可以將同步和異步與Java中的synchronized關鍵字聯系起來進行類比。當多個線程同時訪問一個變量時,每個線程訪問該變量就是一個事件,對於同步來說,就是這些線程必須逐個地來訪問該變量,一個線程在訪問該變量的過程中,其他線程必須等待;而對於異步來說,就是多個線程不必逐個地訪問該變量,可以同時進行訪問。
同步和異步可以表現在很多方面,但是記住其關鍵在於多個任務和事件發生時,一個事件的發生或執行是否會導致整個流程的暫時等待。一般來說,可以通過多線程的方式來實現異步,但是千萬記住不要將多線程和異步畫上等號,異步只是宏觀上的一個模式,采用多線程來實現異步只是一種手段,並且通過多進程的方式也可以實現異步。同步和異步着重點在於多個任務的執行過程中,一個任務的執行是否會導致整個流程的暫時等待
4、.什么是阻塞?什么是非阻塞?
阻塞:
當某個事件或者任務在執行過程中,它發出一個請求操作,但是由於該請求操作需要的條件不滿足,那么就會一直在那等待,直至條件滿足;
非阻塞:
當某個事件或者任務在執行過程中,它發出一個請求操作,如果該請求操作需要的條件不滿足,會立即返回一個標志信息告知條件不滿足,不會一直在那等待。
舉個簡單的例子:
假如我要讀取一個文件中的內容,如果此時文件中沒有內容可讀,對於同步來說就是會一直在那等待,直至文件中有內容可讀;而對於非阻塞來說,就會直接返回一個標志信息告知文件中暫時無內容可讀。
阻塞和非阻塞着重點在於發出一個請求操作時,如果進行操作的條件不滿足是否會返會一個標志信息告知條件不滿足。理解阻塞和非阻塞可以同線程阻塞類比地理解,當一個線程進行一個請求操作時,如果條件不滿足,則會被阻塞,即在那等待條件滿足。
5、什么是阻塞IO?什么是非阻塞IO?
在了解阻塞IO和非阻塞IO之前,先看下一個具體的IO操作過程是怎么進行的。
通常來說,IO操作包括:對硬盤的讀寫、對socket的讀寫以及外設的讀寫。
當用戶線程發起一個IO請求操作(本文以讀請求操作為例),內核會去查看要讀取的數據是否就緒,對於阻塞IO來說,如果數據沒有就緒,則會一直在那等待,直到數據就緒;對於非阻塞IO來說,如果數據沒有就緒,則會返回一個標志信息告知用戶線程當前要讀的數據沒有就緒。當數據就緒之后,便將數據拷貝到用戶線程,這樣才完成了一個完整的IO讀請求操作,也就是說一個完整的IO讀請求操作包括兩個階段:
1)查看數據是否就緒;
2)進行數據拷貝(內核將數據拷貝到用戶線程)。
那么阻塞(blocking IO)和非阻塞(non-blocking IO)的區別就在於第一個階段,如果數據沒有就緒,在查看數據是否就緒的過程中是一直等待,還是直接返回一個標志信息。
Java中傳統的IO都是阻塞IO,比如通過socket來讀數據,調用read()方法之后,如果數據沒有就緒,當前線程就會一直阻塞在read方法調用那里,直到有數據才返回;
而如果是非阻塞IO的話,當數據沒有就緒,read()方法應該返回一個標志信息,告知當前線程數據沒有就緒,而不是一直在那里等待。
6、什么是同步IO?什么是異步IO?
我們先來看一下同步IO和異步IO的定義,在《Unix網絡編程》一書中對同步IO和異步IO的定義是這樣的:
A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes.
An asynchronous I/O operation does not cause the requesting process to be blocked.
從字面的意思可以看出:同步IO即 如果一個線程請求進行IO操作,在IO操作完成之前,該線程會被阻塞;而異步IO為 如果一個線程請求進行IO操作,IO操作不會導致請求線程被阻塞。
事實上,同步IO和異步IO模型是針對用戶線程和內核的交互來說的:
對於同步IO:當用戶發出IO請求操作之后,如果數據沒有就緒,需要通過用戶線程或者內核不斷地去輪詢數據是否就緒,當數據就緒時,再將數據從內核拷貝到用戶線程;
而異步IO:只有IO請求操作的發出是由用戶線程來進行的,IO操作的兩個階段都是由內核自動完成,然后發送通知告知用戶線程IO操作已經完成。也就是說在異步IO中,不會對用戶線程產生任何阻塞。
這是同步IO和異步IO關鍵區別所在,同步IO和異步IO的關鍵區別反映在數據拷貝階段是由用戶線程完成還是內核完成。所以說異步IO必須要有操作系統的底層支持。
注意同步IO和異步IO與阻塞IO和非阻塞IO是不同的兩組概念。
阻塞IO和非阻塞IO是反映在當用戶請求IO操作時,如果數據沒有就緒,是用戶線程一直等待數據就緒,還是會收到一個標志信息這一點上面的。也就是說,阻塞IO和非阻塞IO是反映在IO操作的第一個階段,在查看數據是否就緒時是如何處理的。
7、 IO模型有幾種?分別是什么?
在《Unix網絡編程》一書中提到了五種IO模型
分別是:阻塞IO、非阻塞IO、多路復用IO、信號驅動IO以及異步IO。
下面就分別來介紹一下這5種IO模型的異同。
1.阻塞IO模型
最傳統的一種IO模型,即在讀寫數據過程中會發生阻塞現象。
當用戶線程發出IO請求之后,內核會去查看數據是否就緒,如果沒有就緒就會等待數據就緒,而用戶線程就會處於阻塞狀態,用戶線程交出CPU。當數據就緒之后,內核會將數據拷貝到用戶線程,並返回結果給用戶線程,用戶線程才解除block狀態。
典型的阻塞IO模型的例子為:
data = socket.read();
如果數據沒有就緒,就會一直阻塞在read方法。
2.非阻塞IO模型
當用戶線程發起一個read操作后,並不需要等待,而是馬上就得到了一個結果。如果結果是一個error時,它就知道數據還沒有准備好,於是它可以再次發送read操作。一旦內核中的數據准備好了,並且又再次收到了用戶線程的請求,那么它馬上就將數據拷貝到了用戶線程,然后返回。
所以事實上,在非阻塞IO模型中,用戶線程需要不斷地詢問內核數據是否就緒,也就說非阻塞IO不會交出CPU,而會一直占用CPU。
典型的非阻塞IO模型一般如下:
偽代碼
while(true){
new MyThread(socket)
}
class MyThread{
data = socket.read();
if(data!= error){
處理數據
break;
}
但是對於非阻塞IO就有一個非常嚴重的問題,在while循環中需要不斷地去詢問內核數據是否就緒,這樣會導致CPU占用率非常高,因此一般情況下很少使用while循環這種方式來讀取數據。
3.多路復用IO模型
多路復用IO模型是目前使用得比較多的模型。Java NIO實際上就是多路復用IO。
在多路復用IO模型中,會有一個線程不斷去輪詢多個socket的狀態,只有當socket真正有讀寫事件時,才真正調用實際的IO讀寫操作。因為在多路復用IO模型中,只需要使用一個線程就可以管理多個socket,系統不需要建立新的進程或者線程,也不必維護這些線程和進程,並且只有在真正有socket讀寫事件進行時,才會使用IO資源,所以它大大減少了資源占用。
在Java NIO中,是通過selector.select()去查詢每個通道是否有到達事件,如果沒有事件,則一直阻塞在那里,因此這種方式會導致用戶線程的阻塞。
也許有朋友會說,我可以采用 多線程+ 阻塞IO 達到類似的效果,但是由於在多線程 + 阻塞IO 中,每個socket對應一個線程,這樣會造成很大的資源占用,並且尤其是對於長連接來說,線程的資源一直不會釋放,如果后面陸續有很多連接的話,就會造成性能上的瓶頸。
而多路復用IO模式,通過一個線程就可以管理多個socket,只有當socket真正有讀寫事件發生才會占用資源來進行實際的讀寫操作。因此,多路復用IO比較適合連接數比較多的情況。
另外多路復用IO為何比非阻塞IO模型的效率高是因為在非阻塞IO中,不斷地詢問socket狀態時通過用戶線程去進行的,而在多路復用IO中,輪詢每個socket狀態是內核在進行的,這個效率要比用戶線程要高的多。
不過要注意的是,多路復用IO模型是通過輪詢的方式來檢測是否有事件到達,並且對到達的事件逐一進行響應。因此對於多路復用IO模型來說,一旦事件響應體很大,那么就會導致后續的事件遲遲得不到處理,並且會影響新的事件輪詢。
4.信號驅動IO模型
在信號驅動IO模型中,當用戶線程發起一個IO請求操作,會給對應的socket注冊一個信號函數,然后用戶線程會繼續執行,當內核數據就緒時會發送一個信號給用戶線程,用戶線程接收到信號之后,便在信號函數中調用IO讀寫操作來進行實際的IO請求操作。
5.異步IO模型
異步IO模型才是最理想的IO模型,在異步IO模型中,當用戶線程發起read操作之后,立刻就可以開始去做其它的事。
而另一方面,從內核的角度,當它受到一個asynchronous read之后,它會立刻返回,說明read請求已經成功發起了,因此不會對用戶線程產生任何block。
然后,內核會等待數據准備完成,然后將數據拷貝到用戶線程,當這一切都完成之后,內核會給用戶線程發送一個信號,告訴它read操作完成了。
也就說用戶線程完全不需要實際的整個IO操作是如何進行的,只需要先發起一個請求,當接收內核返回的成功信號時表示IO操作已經完成,可以直接去使用數據了。
也就說在異步IO模型中,IO操作的兩個階段都不會阻塞用戶線程,這兩個階段都是由內核自動完成,然后發送一個信號告知用戶線程操作已完成。
用戶線程中不需要再次調用IO函數進行具體的讀寫。
這點是和信號驅動模型有所不同的
在信號驅動模型中,當用戶線程接收到信號表示數據已經就緒,然后需要用戶線程調用IO函數進行實際的讀寫操作;而在異步IO模型中,收到信號表示IO操作已經完成,不需要再在用戶線程中調用iO函數進行實際的讀寫操作。
注意,異步IO是需要操作系統的底層支持,在Java 7中,提供了Asynchronous IO。也就是java中的AIO
前面四種IO模型實際上都屬於同步IO,只有最后一種是真正的異步IO,因為無論是多路復用IO還是信號驅動模型,IO操作的第2個階段都會引起用戶線程阻塞,也就是內核進行數據拷貝的過程都會讓用戶線程阻塞。
8、 Reactor和Proactor IO設計模式是什么?
在傳統的網絡服務設計模式中,有兩種比較經典的模式:一種是 多線程,一種是線程池。
對於多線程模式,也就說來了client,服務器就會新建一個線程來處理該client的讀寫事件,如下圖所示:
這種模式雖然處理起來簡單方便,但是由於服務器為每個client的連接都采用一個線程去處理,使得資源占用非常大。因此,當連接數量達到上限時,再有用戶請求連接,直接會導致資源瓶頸,嚴重的可能會直接導致服務器崩潰。
因此,為了解決這種一個線程對應一個客戶端模式帶來的問題,提出了采用線程池的方式,也就說創建一個固定大小的線程池,來一個客戶端,就從線程池取一個空閑線程來處理,當客戶端處理完讀寫操作之后,就交出對線程的占用。因此這樣就避免為每一個客戶端都要創建線程帶來的資源浪費,使得線程可以重用。
但是線程池也有它的弊端,如果連接大多是長連接,因此可能會導致在一段時間內,線程池中的線程都被占用,那么當再有用戶請求連接時,由於沒有可用的空閑線程來處理,就會導致客戶端連接失敗,從而影響用戶體驗。因此,線程池比較適合大量的短連接應用。
因此便出現了下面的兩種高性能IO設計模式:Reactor和Proactor。
在Reactor模式中,會先對每個client注冊感興趣的事件,然后有一個線程專門去輪詢每個client是否有事件發生,當有事件發生時,便順序處理每個事件,當所有事件處理完之后,便再轉去繼續輪詢,如下圖所示:
多路復用IO就是采用Reactor模式。注意,上面的圖中展示的 是順序處理每個事件,當然為了提高事件處理速度,可以通過多線程或者線程池的方式來處理事件。
在Proactor模式中,當檢測到有事件發生時,會新起一個異步操作,然后交由內核線程去處理,當內核線程完成IO操作之后,發送一個通知告知操作已完成,可以得知,異步IO模型采用的就是Proactor模式。
9、Java NIO 中的Buffer是什么?如何使用?
Buffer(緩沖區):
Java NIO Buffers用於和NIO Channel交互。 我們從Channel中讀取數據到buffers里,從Buffer把數據寫入到Channels;
Buffer本質上就是一塊內存區;
一個Buffer有三個屬性是必須掌握的,分別是:capacity容量、position位置、limit限制。
Buffer的常見方法
Buffer clear()
Buffer flip()
Buffer rewind()
Buffer position(int newPosition)
Buffer的使用方式/方法介紹:
分配緩沖區(Allocating a Buffer):
ByteBuffer buf = ByteBuffer.allocate(28);//以ByteBuffer為例子
寫入數據到緩沖區(Writing Data to a Buffer)
寫數據到Buffer有兩種方法:
1.從Channel中寫數據到Buffer
int bytesRead = inChannel.read(buf); //read into buffer.
2.通過put寫數據:
buf.put(127);
10、Nio buffer 的內部結構是什么?
一個 buffer 主要由 position,limit,capacity 三個變量來控制讀寫的過程。此三個變量的含義見如下表格:
| 參數 |
寫模式 |
讀模式 |
| position |
當前寫入的單位數據數量。 |
當前讀取的單位數據位置。 |
| limit |
代表最多能寫多少單位數據和容量是一樣的。 |
代表最多能讀多少單位數據,和之前寫入的單位數據量一致。 |
| capacity |
buffer 容量 |
buffer 容量 |
Buffer 常見方法:
flip(): 寫模式轉換成讀模式
rewind() :將 position 重置為 0 ,一般用於重復讀。
clear() :清空 buffer ,准備再次被寫入 (position 變成 0 , limit 變成 capacity) 。
compact(): 將未讀取的數據拷貝到 buffer 的頭部位。
mark() 、 reset():mark 可以標記一個位置, reset 可以重置到該位置。
Buffer 常見類型: ByteBuffer 、 MappedByteBuffer 、 CharBuffer 、 DoubleBuffer 、 FloatBuffer 、 IntBuffer 、LongBuffer 、 ShortBuffer 。
channel 常見類型 :FileChannel 、 DatagramChannel(UDP) 、 SocketChannel(TCP) 、 ServerSocketChannel(TCP)
11、Java NIO 中的 Channel是什么?有什么特點?
Channel:
Java NIO中的SocketChannel是一個連接到TCP網絡套接字的通道。
可以通過以下2種方式創建SocketChannel:
- 打開一個SocketChannel並連接到互聯網上的某台服務器。
- 一個新連接到達ServerSocketChannel時,會創建一個SocketChannel。
打開 SocketChannel 下面是SocketChannel的打開方式:
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
關閉 SocketChannel
當用完SocketChannel之后調用SocketChannel.close()關閉SocketChannel: socketChannel.close();
從 SocketChannel 讀取數據
要從SocketChannel中讀取數據,調用一個read()的方法之一。
ByteBuffer buf = ByteBuffer.allocate(48);
int bytesRead = socketChannel.read(buf);
非阻塞模式
可以設置 SocketChannel 為非阻塞模式(non-blocking mode).設置之后,就可以在異步模式下調用connect(), read() 和write()了。
如果SocketChannel在非阻塞模式下,此時調用connect(),該方法可能在連接建立之前就返回了。為了確定連接是否建立,可以調用finishConnect()的方法。
像這樣:
socketChannel.configureBlocking(false);
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
while(! socketChannel.finishConnect() ){
//wait, or do something else...
}
Java NIO Channel通道和流非常相似,主要有以下幾點區別:
l 通道可以讀也可以寫,流一般來說是單向的(只能讀或者寫,所以之前我們用流進行IO操作的時候需要分別創建一個輸入流和一個輸出流)。
l 通道可以異步讀寫。
l 通道總是基於緩沖區Buffer來讀寫。
Java NIO中最重要的幾個Channel的實現:
l FileChannel: 用於文件的數據讀寫
l DatagramChannel: 用於UDP的數據讀寫
l SocketChannel: 用於TCP的數據讀寫,一般是客戶端實現
l ServerSocketChannel: 允許我們監聽TCP鏈接請求,每個請求會創建會一個SocketChannel,一般是服務器實現
類層次結構
12、Java NIO中的Selector是什么?
Selector(選擇器):
Selector 一般稱 為選擇器 ,當然你也可以翻譯為 多路復用器 。
它是Java NIO核心組件中的一個,用於檢查一個或多個NIO Channel(通道)的狀態是否處於可讀、可寫。
如此可以實現單線程管理多個channels,也就是可以管理多個網絡鏈接。
使用Selector的好處在於: 使用更少的線程來就可以來處理通道了, 相比使用多個線程,避免了線程上下文切換帶來的開銷。
Selector(選擇器)的使用方法介紹
Selector的創建
Selector selector = Selector.open();
注冊Channel到Selector(Channel必須是非阻塞的)
channel.configureBlocking(false);
SelectionKey key = channel.register(selector, Selectionkey.OP_READ);
SelectionKey介紹
一個SelectionKey鍵表示了一個特定的通道對象和一個特定的選擇器對象之間的注冊關系。
從Selector中選擇channel(Selecting Channels via a Selector)
選擇器維護注冊過的通道的集合,並且這種注冊關系都被封裝在SelectionKey當中.
停止選擇的方法
wakeup()方法 和close()方法。
13、簡單講一下文件IO中的Path和Files
文件I/O基石:Path:
創建一個Path
File和Path之間的轉換,File和URI之間的轉換
獲取Path的相關信息
移除Path中的冗余項
Files類:
Files.exists() 檢測文件路徑是否存在
Files.createFile() 創建文件
Files.createDirectories()和Files.createDirectory()創建文件夾
Files.delete()方法 可以刪除一個文件或目錄
Files.copy()方法可以吧一個文件從一個地址復制到另一個位置
獲取文件屬性
遍歷一個文件夾
Files.walkFileTree()遍歷整個目錄
14、select、poll和epoll的區別
在linux 沒有實現epoll事件驅動機制之前,我們一般選擇用select或者poll等IO多路復用的方法來實現並發服務程序。在大數據、高並發、集群等一些名詞唱得火熱之年代,select和poll的用武之地越來越有限,風頭已經被epoll占盡。
select的缺點:
- 單個進程能夠監視的文件描述符的數量存在最大限制,通常是1024,當然可以更改數量,但由於select采用輪詢的方式掃描文件描述符,文件描述符數量越多,性能越差;
在linux內核頭文件中,有這樣的定義:
#define __FD_SETSIZE 1024
- 內核 / 用戶空間內存拷貝問題,select需要復制大量的句柄數據結構,產生巨大的開銷;
- select返回的是含有整個句柄的數組,應用程序需要遍歷整個數組才能發現哪些句柄發生了事件;
- select的觸發方式是水平觸發,應用程序如果沒有完成對一個已經就緒的文件描述符進行IO操作,那么之后每次select調用還是會將這些文件描述符通知進程。
相比select模型,poll使用鏈表保存文件描述符,因此沒有了監視文件數量的限制,但其他三個缺點依然存在。
拿select模型為例,假設我們的服務器需要支持100萬的並發連接,則在__FD_SETSIZE 為1024的情況下,則我們至少需要開辟1k個進程才能實現100萬的並發連接。
除了進程間上下文切換的時間消耗外,從內核/用戶空間大量的無腦內存拷貝、數組輪詢等,是系統難以承受的。
因此,基於select模型的服務器程序,要達到10萬級別的並發訪問,是一個很難完成的任務。
epoll的實現機制與select/poll機制完全不同,上面所說的 select的缺點在epoll上不復存在。
設想一下如下場景:
有100萬個客戶端同時與一個服務器進程保持着TCP連接。而每一時刻,通常只有幾百上千個TCP連接是活躍的(事實上大部分場景都是這種情況)。如何實現這樣的高並發?
在select/poll時代,服務器進程每次都把這100萬個連接告訴操作系統(從用戶態復制句柄數據結構到內核態),讓操作系統內核去查詢這些套接字上是否有事件發生,輪詢完后,再將句柄數據復制到用戶態,讓服務器應用程序輪詢處理已發生的網絡事件,這一過程資源消耗較大,因此,select/poll一般只能處理幾千的並發連接。
epoll的設計和實現與select完全不同。
epoll通過在Linux內核中申請一個簡易的文件系統
(文件系統一般用什么數據結構實現?B+樹)
把原先的select/poll調用分成了3個部分:
1)調用epoll_create()建立一個epoll對象(在epoll文件系統中為這個句柄對象分配資源)
2)調用epoll_ctl向epoll對象中添加這100萬個連接的套接字
3)調用epoll_wait收集發生的事件的連接
如此一來,要實現上面說是的場景,只需要在進程啟動時建立一個epoll對象,然后在需要的時候向這個epoll對象中添加或者刪除連接。同時,epoll_wait的效率也非常高,因為調用epoll_wait時,並沒有一股腦的向操作系統復制這100萬個連接的句柄數據,內核也不需要去遍歷全部的連接。
下面來看看Linux內核具體的epoll機制實現思路。
當某一進程調用epoll_create方法時,Linux內核會創建一個eventpoll結構體,這個結構體中有兩個成員與epoll的使用方式密切相關。eventpoll結構體如下所示:
struct eventpoll{
....
/*紅黑樹的根節點,這顆樹中存儲着所有添加到epoll中的需要監控的事件*/
struct rb_root rbr;
/*雙鏈表中則存放着將要通過epoll_wait返回給用戶的滿足條件的事件*/
struct list_head rdlist;
....
};
每一個epoll對象都有一個獨立的eventpoll結構體,用於存放通過epoll_ctl方法向epoll對象中添加進來的事件。這些事件都會掛載在紅黑樹中,如此,重復添加的事件就可以通過紅黑樹而高效的識別出來(紅黑樹的插入時間效率是lgn,其中n為樹的高度)。
而所有添加到epoll中的事件都會與設備(網卡)驅動程序建立回調關系,也就是說,當相應的事件發生時會調用這個回調方法。這個回調方法在內核中叫ep_poll_callback,它會將發生的事件添加到rdlist雙鏈表中。
在epoll中,對於每一個事件,都會建立一個epitem結構體,如下所示:
struct epitem{
struct rb_node rbn;//紅黑樹節點
struct list_head rdllink;//雙向鏈表節點
struct epoll_filefd ffd; //事件句柄信息
struct eventpoll *ep; //指向其所屬的eventpoll對象
struct epoll_event event; //期待發生的事件類型
}
當調用epoll_wait檢查是否有事件發生時,只需要檢查eventpoll對象中的rdlist雙鏈表中是否有epitem元素即可。如果rdlist不為空,則把發生的事件復制到用戶態,同時將事件數量返回給用戶。
通過紅黑樹和雙鏈表數據結構,並結合操作系統底層回調機制,造就了epoll的高效
epoll的用法
第一步:epoll_create()系統調用。此調用返回一個句柄,之后所有的使用都依靠這個句柄來標識。
第二步:epoll_ctl()系統調用。通過此調用向epoll對象中添加、刪除、修改感興趣的事件,返回0標識成功,返回-1表示失敗。
第三部:epoll_wait()系統調用。通過此調用收集收集在epoll監控中已經發生的事件。
15、網絡編程中設計並發服務器,使用多進程 與 多線程 ,請問有什么區別?
1,進程:
子進程是父進程的復制品。
子進程獲得父進程數據空間、堆和棧的復制品。
2,線程:
相對與進程而言,線程是一個更加接近與執行體的概念,它可以與同進程的其他線程共享數據,但擁有自己的棧空間,擁有獨立的執行序列。
兩者都可以提高程序的並發度,提高程序運行效率和響應時間。
線程和進程在使用上各有優缺點:
線程執行開銷小,但不利於資源管理和保護;而進程正相反。
同時,線程適合於在SMP機器上運行,而進程則可以跨機器遷移。
SMP的全稱是"對稱多處理"(Symmetrical Multi-Processing)技術,是指在一個計算機上匯集了一組處理器(多CPU),各CPU之間共享內存子系統以及總線結構。
15、網絡編程的一般步驟
對於TCP連接:
1.服務器端
1)創建套接字create;
2)綁定端口號bind;
3)監聽連接listen;
4)接受連接請求accept,並返回新的套接字;
5)用新返回的套接字recv/send;
6)關閉套接字。
2.客戶端
1)創建套接字create;
2)發起建立連接請求connect;
3)發送/接收數據send/recv;
4)關閉套接字。
TCP總結:
Server端:create – bind – listen– accept– recv/send– close
Client端:create——- conncet——send/recv——close.
對於UDP連接:
1.服務器端:
1)創建套接字create;
2)綁定端口號bind;
3)接收/發送消息recvfrom/sendto;
4)關閉套接字。
2.客戶端:
1)創建套接字create;
2)發送/接收消息sendto/recvfrom;
3)關閉套接字.
UDP總結:
Server端:create—-bind —-recvfrom/sendto—-close
Client端:create—- sendto/recvfrom—-close.
函數原型int recv( _In_ SOCKET s, _Out_ char *buf, _In_ int len, _In_ int flags);
16、TCP的全稱是?
Transfer Control Protocol。
17、UDP的全稱是?
User Datagram Protocol。
18、請說出TCP和UDP的區別?
TCP:
一種面向連接(連接導向)的、可靠的、基於字節流的傳輸層(Transport layer)通信協議 。
特點:
面向連接;
點到點的通信;
高可靠性;
占用系統資源多、效率低;
UDP:
一種無連接的、提供面向事務的簡單不可靠信息傳送服務的傳輸層通信協議。
特點:
非面向連接
傳輸不可靠,可能丟失
發送不管對方是否准備好,接收方收到也不確認
可以廣播發送
非常簡單的協議,開銷小
TCP—傳輸控制協議,提供的是面向連接、可靠的字節流服務。當客戶和服務器彼此交換數據前,必須先在雙方之間建立一個TCP連接,之后才能傳輸數據。TCP提供超時重發,丟棄重復數據,檢驗數據,流量控制等功能,保證數據能從一端傳到另一端。
UDP—用戶數據報協議,是一個簡單的面向數據報的運輸層協議。UDP不提供可靠性,它只是把應用程序傳給IP層的數據報發送出去,但是並不能保證它們能到達目的地。由於UDP在傳輸數據報前不用在客戶和服務器之間建立一個連接,且沒有超時重發等機制,故而傳輸速度很快
19、TCP為什么不是兩次連接?而是三次握手?
如果A與B兩個進程通信,如果僅是兩次連接。
可能出現的一種情況
就是:A發送完請求報文以后,由於網絡情況不好,出現了網絡擁塞,即B延時很長時間后收到報文,即此時A將此報文認定為失效的報文。
B收到報文后,會向A發起連接。此時兩次握手完畢
B會認為已經建立了連接可以通信,B會一直等到A發送的連接請求
而A對失效的報文回復自然不會處理。
因此會陷入B忙等的僵局,造成資源的浪費。
20、說明socket是什么?
從上圖可以看到:底層的東西已經被內核實現了,即我們通常意義上的內核協議棧(傳輸層,網絡層,鏈路層)
最上面的Application(應用層)是我們用戶所要實現的,它是屬於用戶進程的一部分,工作在用戶空間,那么用戶空間的程序要想訪問內核,使用內核的服務,就需要一個接口,去訪問所需要的服務
對於網絡編程來說,這個接口就是套接口(Socket)。
Socket:可以看作用戶進程和內核網絡協議棧編程(交互)接口
Socket:不僅可以在同一台主機上進行通信,也可以在網絡上不同的主機間進行通信,也可以異構(軟硬件平台不同)進行通信(手機qq和PC機上的qq進行通信,手機的系統是ARM,而PC機是x86)
21、為什么需要端口?端口是真實存在的還是虛擬的概念?
IP地址用來標志一台計算機,但是一台計算機上可能提供多種網絡應用程序,使用端口來區分這些應用程序。
端口是虛擬的概念,並不是說在主機上真的有若干個端口。通過端口,可以在一個主機上運行多個網絡應用程序。
端口范圍0---65535,16位整數。
22、Java中,端口使用兩個字節表示,可以表示多少個端口? UDP和TCP端口是各自獨立的嗎?
端口范圍0---65535,16位整數。
由於TCP/IP傳輸層的兩個協議TCP和UDP是完全獨立的兩個軟件模塊,因此各自的端口號也相互獨立,如TCP有一個255號端口,UDP也可以有一個255號端口,二者並不沖突。
23、URL類有什么作用?
URL:Uniform Resource Locator,統一資源定位器;俗稱“網址”,如:
"http://www.baidu.com:80/index.html#aa?cansu=bjsxt“
由4部分組成:
l 協議: http;
l 存放資源的主機域名:www.baidu.com;
l 端口號:80;
l 資源文件名: index.html#aa?cansu=bjsxt;
URL是指向互聯網“資源”的指針。資源可以是簡單的文件或目錄,也可以是對更為復雜的對象的引用,例如對數據庫或搜索引擎的查詢。
24、基於TCP的Socket網絡編程的主要步驟是什么?
基於TCP協議的Socket編程的主要步驟
服務器端(server):
1. 構建一個ServerSocket實例,指定本地的端口。這個socket就是用來監聽指定端口的連接請求的。
2.重復如下幾個步驟:
a. 調用socket的accept()方法來獲得下面客戶端的連接請求。通過accept()方法返回的socket實例,建立了一個和客戶端的新連接。
b.通過這個返回的socket實例獲取InputStream和OutputStream,可以通過這兩個stream來分別讀和寫數據。
c.結束的時候調用socket實例的close()方法關閉socket連接。
客戶端(client):
1.構建Socket實例,通過指定的遠程服務器地址和端口來建立連接。
2.通過Socket實例包含的InputStream和OutputStream來進行數據的讀寫。
3.操作結束后調用socket實例的close方法,關閉。
25、【上機】寫出建立TCP服務器ServerSocket的代碼。並說明accept方法有什么特點?
//服務器監聽請求;
ServerSocket ss=new ServerSocket(9999);
//接受請求:創建了socket;
Socket socket=ss.accept();
詳見課上示例。
26、【上機】寫出建立TCP客戶端Socket的代碼。並說明建立Socket后,通過什么方法Socket獲得流對象?
//客戶端向服務器端發送請求;
Socket socket=new Socket("127.0.0.1",9999);
//建好連接后,開始傳輸數據;
OutputStream os=socket.getOutputStream();
詳見課上示例。
27、基於UDP的Socket網絡編程的主要步驟是什么?
基於UDP協議的Socket編程的主要步驟
服務器端(server):
1. 構造DatagramSocket實例,指定本地端口。
2. 通過DatagramSocket實例的receive方法接收DatagramPacket.DatagramPacket中間就包含了通信的內容。
3. 通過DatagramSocket的send和receive方法來收和發DatagramPacket.
客戶端(client):
1. 構造DatagramSocket實例。
2.通過DatagramSocket實例的send和receive方法發送DatagramPacket報文。
3.結束后,調用DatagramSocket的close方法關閉。
28、【上機】使用UDP的方式,完成對象的傳遞。
(1)客戶端向服務器端傳送對象信息;
DatagramSocket ds=new DatagramSocket(9999);
//構建數據包;
Scanner input=new Scanner(System.in);
System.out.println("請輸入用戶名:");
String username=input.nextLine();
System.out.println("請輸入密碼:");
String password=input.nextLine();
//事先要創建好User類;
User user=new User(username,password);
//字節流;在內存開辟緩沖區;
ByteArrayOutputStream baos=new ByteArrayOutputStream();
ObjectOutputStream oos=new ObjectOutputStream(baos);
oos.writeObject(user);
byte buf[]=baos.toByteArray();
DatagramPacket dp=new DatagramPacket(buf, buf.length, InetAddress.getByName("127.0.0.1"), 8888);//DatagramPacket只用byte[]數組;
//發送數據;
ds.send(dp);
(2)服務器端從客戶端接收對象信息;
//服務器定義DatagramSocket以接收數據;
DatagramSocket ds=new DatagramSocket(8888);
//定義一個數據包來接收數據;
//數據包里是byte數組,所以還得定義一個byte數組;
byte buf[]=new byte[1024];
DatagramPacket dp=new DatagramPacket(buf, buf.length);
//接收客戶端發過來的數據;
ds.receive(dp);
//用字節流和對象流讀取對象信息;
ByteArrayInputStream bais=new ByteArrayInputStream(buf);
ObjectInputStream ois=new ObjectInputStream(bais);
User user=(User)ois.readObject();
System.out.println(user);
詳見課上示例。
29、HTTPClient相關問題
- 什么是httpClient?
- 什么是HttpClient不能做的?
- HttpClient有哪些特性?
- HttpClient怎樣發送帶參數的GET請求?
- HttpClient怎樣發送帶參數的POST請求?
- HttpClient怎樣獲取響應狀態?
- HttpClient怎樣獲取響應內容?
- HttpClient怎樣上傳文件?
30、NIO 和傳統 BIO區別是什么?
NIO vs BIO之間的理念上面的區別(NIO將阻塞交給了后台線程執行)
IO是面向流的,NIO是面向緩沖區的
Java BIO面向流意味着每次從流中讀一個或多個字節,直至讀取所有字節,它們沒有被緩存在任何地方;
NIO則能前后移動流中的數據,因為是面向緩沖區的 BIO流是阻塞的,NIO流是不阻塞的 Java IO的各種流是阻塞的。
這意味着,當一個線程調用read() 或 write()時,該線程被阻塞,直到有一些數據被讀取,或數據完全寫入。
該線程在此期間不能再干任何事情了 Java NIO的非阻塞模式,使一個線程從某通道發送請求讀取數據,但是它僅能得到目前可用的數據,如果目前沒有數據可用時,就什么都不會獲取。
NIO可讓您只使用一個(或幾個)單線程管理多個通道(網絡連接或文件),但付出的代價是解析數據可能會比從一個阻塞流中讀取數據更復雜。
非阻塞寫也是如此。一個線程請求寫入一些數據到某通道,但不需要等待它完全寫入,這個線程同時可以去做別的事情。
選擇器
Java NIO的選擇器允許一個單獨的線程來監視多個輸入通道,你可以注冊多個通道使用一個選擇器,然后使用一個單獨的線程來“選擇”通道:這些通道里已經有可以處理的輸入,或者選擇已准備寫入的通道。這種選擇機制,使得一個單獨的線程很容易來管理多個通道。
31、Java NIO 的幾個核心組成部分是什么?作用分別是什么?
l Channels
l Buffers
l Selectors
基本上,所有的 IO 在NIO 中都從一個Channel 開始。
Channel 有點象流。
數據可以從Channel讀到Buffer中,也可以從Buffer 寫到Channel中。
Channel的實現:
(涵蓋了UDP 和 TCP 網絡IO,以及文件IO)
l FileChannel
l DatagramChannel
l SocketChannel
l ServerSocketChannel
讀數據:
int bytesRead = inChannel.read(buf);
寫數據:
int bytesWritten = inChannel.write(buf);
Buffer
Buffer實現: (byte, char、short, int, long, float, double )
l ByteBuffer
l CharBuffer
l DoubleBuffer
l FloatBuffer
l IntBuffer
l LongBuffer
l ShortBuffer
Buffer使用
l 讀數據 flip()方法:
buf.flip();
將Buffer從寫模式切換到讀模式 調用flip()方法會將position設回0,並將limit設置成之前position的值。
l (char) buf.get()
讀取數據
l Buffer.rewind()
將position設回0,所以你可以重讀Buffer中的所有數據 limit保持不變,仍然表示能從Buffer中讀取多少個元素(byte、char等)
l Buffer.mark()方法,
可以標記Buffer中的一個特定position。
之后可以通過調用 Buffer.reset()方法,恢復到Buffer.mark()標記時的position
一旦讀完了所有的數據,就需要清空緩沖區,讓它可以再次被寫入。
l clear()方法:
清空整個緩沖區。 position將被設回0,limit被設置成 capacity的值
l compact()方法:
只會清除已經讀過的數據;任何未讀的數據都被移到緩沖區的起始處,新寫入的數據將放到緩沖區未讀數據的后面。
將position設到最后一個未讀元素正后面,limit被設置成 capacity的值 寫數據 buf.put(127);
Buffer的三個屬性
capacity:
l 表示容量
l Buffer的一個固定的大小值;
l Buffer滿了需要將其清空才能再寫;
l ByteBuffer.allocate(48);該buffer的capacity為48byte CharBuffer.allocate(1024);該buffer的capacity為1024個char
position:
含義取決於Buffer處在讀模式還是寫模式(初始值為0,寫或者讀操作的當前位置)
寫數據時,初始的position值為0;
其值最大可為capacity-1
將Buffer從寫模式切換到讀模式,position會被重置為0
limit:
含義取決於Buffer處在讀模式還是寫模式(寫limit=capacity;讀limit等於最多可以讀取到的數據)
寫模式下,limit等於Buffer的capacity 切換Buffer到讀模式時, limit表示你最多能讀到多少數據;
Selector
Selector允許單線程處理多個 Channel。
如果你的應用打開了多個連接(通道),但每個連接的流量都很低,使用Selector就會很方便。
例如,在一個聊天服務器中。
要使用Selector,得向Selector注冊Channel,然后調用它的select()方法。這個方法會一直阻塞到某個注冊的通道有事件就緒。
一旦這個方法返回,線程就可以處理這些事件,事件的例子有如新連接進來,數據接收等。
使用
創建:
Selector selector = Selector.open(); 注冊通道: channel.configureBlocking(false); //與Selector一起使用時,Channel必須處於非阻塞模式
//這意味着不能將FileChannel與Selector一起使用,因為FileChannel不能切換到非阻塞模式(而套接字通道都可以)
SelectionKey key = channel.register(selector, Selectionkey.OP_READ); //第二個參數表明Selector監聽Channel時對什么事件感興趣
//SelectionKey.OP_CONNECT SelectionKey.OP_ACCEPT SelectionKey.OP_READ SelectionKey.OP_WRITE //可以用或操作符將多個興趣組合一起
SelectionKey 包含了interest集合 、ready集合 、Channel 、Selector 、附加的對象(可選)
int interestSet = key.interestOps();
可以進行類似interestSet & SelectionKey.OP_CONNECT的判斷
select():
阻塞到至少有一個通道在你注冊的事件上就緒了
selectNow():
不會阻塞,不管什么通道就緒都立刻返回
selectedKeys():
訪問“已選擇鍵集(selected key set)”中的就緒通道
close():
使用完selector需要用其close()方法會關閉該Selector,且使注冊到該Selector上的所有SelectionKey實例無效
Set selectedKeys = selector.selectedKeys();
Iterator keyIterator = selectedKeys.iterator();
while(keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
if(key.isAcceptable()) {
// a connection was accepted by a ServerSocketChannel.
} else if (key.isConnectable()) {
// a connection was established with a remote server.
} else if (key.isReadable()) {
// a channel is ready for reading
} else if (key.isWritable()) {
// a channel is ready for writing
}
keyIterator.remove();//注意這里必須手動remove;
表明該selectkey我已經處理過了;
}
32、簡單說一下http協議?
HTTP協議是Hyper Text Transfer Protocol(超文本傳輸協議)的縮寫,是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。
HTTP是一個基於TCP/IP通信協議來傳遞數據(HTML 文件, 圖片文件, 查詢結果等)。
HTTP 工作原理
HTTP協議工作於客戶端-服務端架構上。瀏覽器作為HTTP客戶端通過URL向HTTP服務端即WEB服務器發送所有請求。
Web服務器有:Apache服務器,Nginx,IIS服務器(Internet Information Services)等。
Web服務器根據接收到的請求后,向客戶端發送響應信息。
HTTP默認端口號為80,但是你也可以改為8080或者其他端口。
HTTP三點注意事項:
l HTTP是無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答后,即斷開連接。采用這種方式可以節省傳輸時間。
l HTTP是媒體獨立的:這意味着,只要客戶端和服務器知道如何處理的數據內容,任何類型的數據都可以通過HTTP發送。客戶端以及服務器指定使用適合的MIME-type內容類型。
l HTTP是無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。
33、http協議下客戶端請求報文是什么?
客戶端發送一個HTTP請求到服務器的請求消息包括以下格式:
l 請求行(request line)
l 請求頭部(header)
l 空行
l 請求數據
四個部分組成
下圖給出了請求報文的一般格式。
客戶端請求:
GET /hello.txt HTTP/1.1
User-Agent: curl/7.16.3 libcurl/7.16.3 OpenSSL/0.9.7l zlib/1.2.3
Host: www.example.com
Accept-Language: en, mi
34、描述一下http協議服務器響應報文有哪些?
HTTP響應也由四個部分組成,分別是:
l 狀態行
l 消息報頭
l 空行
l 響應正文
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
ETag: "34aa387-d-1568eb00"
Accept-Ranges: bytes
Content-Length: 51
Vary: Accept-Encoding
Content-Type: text/plain
35、HTTP協議中常用的請求方法有哪些
根據HTTP標准,HTTP請求可以使用多種請求方法。
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法。
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
| 序號 |
方法 |
描述 |
| 1 |
GET |
請求指定的頁面信息,並返回實體主體。 |
| 2 |
HEAD |
類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 |
| 3 |
POST |
向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。 POST請求可能會導致新的資源的建立和/或已有資源的修改。 |
| 4 |
PUT |
從客戶端向服務器傳送的數據取代指定的文檔的內容。 |
| 5 |
DELETE |
請求服務器刪除指定的頁面。 |
| 6 |
CONNECT |
HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。 |
| 7 |
OPTIONS |
允許客戶端查看服務器的性能。 |
| 8 |
TRACE |
回顯服務器收到的請求,主要用於測試或診斷。 |
36、常見的HTTP狀態碼有哪些
當瀏覽者訪問一個網頁時,瀏覽者的瀏覽器會向網頁所在服務器發出請求。當瀏覽器接收並顯示網頁前,此網頁所在的服務器會返回一個包含HTTP狀態碼的信息頭(server header)用以響應瀏覽器的請求。
HTTP狀態碼的英文為HTTP Status Code。
下面是常見的HTTP狀態碼:
l 200 - 請求成功
l 301 - 資源(網頁等)被永久轉移到其它URL
l 404 - 請求的資源(網頁等)不存在
l 500 - 內部服務器錯誤
HTTP狀態碼由三個十進制數字組成,第一個十進制數字定義了狀態碼的類型,后兩個數字沒有分類的作用。HTTP狀態碼共分為5種類型:
| HTTP狀態碼分類 |
|
| 分類 |
分類描述 |
| 1** |
信息,服務器收到請求,需要請求者繼續執行操作 |
| 2** |
成功,操作被成功接收並處理 |
| 3** |
重定向,需要進一步的操作以完成請求 |
| 4** |
客戶端錯誤,請求包含語法錯誤或無法完成請求 |
| 5** |
服務器錯誤,服務器在處理請求的過程中發生了錯誤 |
HTTP狀態碼列表:
| HTTP狀態碼列表 |
||
| 狀態碼 |
狀態碼英文名稱 |
中文描述 |
| 100 |
Continue |
繼續。客戶端應繼續其請求 |
| 101 |
Switching Protocols |
切換協議。服務器根據客戶端的請求切換協議。只能切換到更高級的協議,例如,切換到HTTP的新版本協議 |
|
|
||
| 200 |
OK |
請求成功。一般用於GET與POST請求 |
| 201 |
Created |
已創建。成功請求並創建了新的資源 |
| 202 |
Accepted |
已接受。已經接受請求,但未處理完成 |
| 203 |
Non-Authoritative Information |
非授權信息。請求成功。但返回的meta信息不在原始的服務器,而是一個副本 |
| 204 |
No Content |
無內容。服務器成功處理,但未返回內容。在未更新網頁的情況下,可確保瀏覽器繼續顯示當前文檔 |
| 205 |
Reset Content |
重置內容。服務器處理成功,用戶終端(例如:瀏覽器)應重置文檔視圖。可通過此返回碼清除瀏覽器的表單域 |
| 206 |
Partial Content |
部分內容。服務器成功處理了部分GET請求 |
|
|
||
| 300 |
Multiple Choices |
多種選擇。請求的資源可包括多個位置,相應可返回一個資源特征與地址的列表用於用戶終端(例如:瀏覽器)選擇 |
| 301 |
Moved Permanently |
永久移動。請求的資源已被永久的移動到新URI,返回信息會包括新的URI,瀏覽器會自動定向到新URI。今后任何新的請求都應使用新的URI代替 |
| 302 |
Found |
臨時移動。與301類似。但資源只是臨時被移動。客戶端應繼續使用原有URI |
| 303 |
See Other |
查看其它地址。與301類似。使用GET和POST請求查看 |
| 304 |
Not Modified |
未修改。所請求的資源未修改,服務器返回此狀態碼時,不會返回任何資源。客戶端通常會緩存訪問過的資源,通過提供一個頭信息指出客戶端希望只返回在指定日期之后修改的資源 |
| 305 |
Use Proxy |
使用代理。所請求的資源必須通過代理訪問 |
| 306 |
Unused |
已經被廢棄的HTTP狀態碼 |
| 307 |
Temporary Redirect |
臨時重定向。與302類似。使用GET請求重定向 |
|
|
||
| 400 |
Bad Request |
客戶端請求的語法錯誤,服務器無法理解 |
| 401 |
Unauthorized |
請求要求用戶的身份認證 |
| 402 |
Payment Required |
保留,將來使用 |
| 403 |
Forbidden |
服務器理解請求客戶端的請求,但是拒絕執行此請求 |
| 404 |
Not Found |
服務器無法根據客戶端的請求找到資源(網頁)。通過此代碼,網站設計人員可設置"您所請求的資源無法找到"的個性頁面 |
| 405 |
Method Not Allowed |
客戶端請求中的方法被禁止 |
| 406 |
Not Acceptable |
服務器無法根據客戶端請求的內容特性完成請求 |
| 407 |
Proxy Authentication Required |
請求要求代理的身份認證,與401類似,但請求者應當使用代理進行授權 |
| 408 |
Request Time-out |
服務器等待客戶端發送的請求時間過長,超時 |
| 409 |
Conflict |
服務器完成客戶端的PUT請求是可能返回此代碼,服務器處理請求時發生了沖突 |
| 410 |
Gone |
客戶端請求的資源已經不存在。410不同於404,如果資源以前有現在被永久刪除了可使用410代碼,網站設計人員可通過301代碼指定資源的新位置 |
| 411 |
Length Required |
服務器無法處理客戶端發送的不帶Content-Length的請求信息 |
| 412 |
Precondition Failed |
客戶端請求信息的先決條件錯誤 |
| 413 |
Request Entity Too Large |
由於請求的實體過大,服務器無法處理,因此拒絕請求。為防止客戶端的連續請求,服務器可能會關閉連接。如果只是服務器暫時無法處理,則會包含一個Retry-After的響應信息 |
| 414 |
Request-URI Too Large |
請求的URI過長(URI通常為網址),服務器無法處理 |
| 415 |
Unsupported Media Type |
服務器無法處理請求附帶的媒體格式 |
| 416 |
Requested range not satisfiable |
客戶端請求的范圍無效 |
| 417 |
Expectation Failed |
服務器無法滿足Expect的請求頭信息 |
|
|
||
| 500 |
Internal Server Error |
服務器內部錯誤,無法完成請求 |
| 501 |
Not Implemented |
服務器不支持請求的功能,無法完成請求 |
| 502 |
Bad Gateway |
充當網關或代理的服務器,從遠端服務器接收到了一個無效的請求 |
| 503 |
Service Unavailable |
由於超載或系統維護,服務器暫時的無法處理客戶端的請求。延時的長度可包含在服務器的Retry-After頭信息中 |
| 504 |
Gateway Time-out |
充當網關或代理的服務器,未及時從遠端服務器獲取請求 |
| 505 |
HTTP Version not supported |
服務器不支持請求的HTTP協議的版本,無法完成處理 |
37、HTTP 協議中content-type指的是什么?
Content-Type,內容類型,一般是指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼,決定瀏覽器將以什么形式、什么編碼讀取這個文件,這就是經常看到一些Asp網頁點擊的結果卻是下載到的一個文件或一張圖片的原因。
| 文件擴展名 |
Content-Type(Mime-Type) |
文件擴展名 |
Content-Type(Mime-Type) |
| .*( 二進制流,不知道下載文件類型) |
application/octet-stream |
.tif |
image/tiff |
| .001 |
application/x-001 |
.301 |
application/x-301 |
| .323 |
text/h323 |
.906 |
application/x-906 |
| .907 |
drawing/907 |
.a11 |
application/x-a11 |
| .acp |
audio/x-mei-aac |
.ai |
application/postscript |
| .aif |
audio/aiff |
.aifc |
audio/aiff |
| .aiff |
audio/aiff |
.anv |
application/x-anv |
| .asa |
text/asa |
.asf |
video/x-ms-asf |
| .asp |
text/asp |
.asx |
video/x-ms-asf |
| .au |
audio/basic |
.avi |
video/avi |
| .awf |
application/vnd.adobe.workflow |
.biz |
text/xml |
| .bmp |
application/x-bmp |
.bot |
application/x-bot |
| .c4t |
application/x-c4t |
.c90 |
application/x-c90 |
| .cal |
application/x-cals |
.cat |
application/vnd.ms-pki.seccat |
| .cdf |
application/x-netcdf |
.cdr |
application/x-cdr |
| .cel |
application/x-cel |
.cer |
application/x-x509-ca-cert |
| .cg4 |
application/x-g4 |
.cgm |
application/x-cgm |
| .cit |
application/x-cit |
.class |
java/* |
| .cml |
text/xml |
.cmp |
application/x-cmp |
| .cmx |
application/x-cmx |
.cot |
application/x-cot |
| .crl |
application/pkix-crl |
.crt |
application/x-x509-ca-cert |
| .csi |
application/x-csi |
.css |
text/css |
| .cut |
application/x-cut |
.dbf |
application/x-dbf |
| .dbm |
application/x-dbm |
.dbx |
application/x-dbx |
| .dcd |
text/xml |
.dcx |
application/x-dcx |
| .der |
application/x-x509-ca-cert |
.dgn |
application/x-dgn |
| .dib |
application/x-dib |
.dll |
application/x-msdownload |
| .doc |
application/msword |
.dot |
application/msword |
| .drw |
application/x-drw |
.dtd |
text/xml |
| .dwf |
Model/vnd.dwf |
.dwf |
application/x-dwf |
| .dwg |
application/x-dwg |
.dxb |
application/x-dxb |
| .dxf |
application/x-dxf |
.edn |
application/vnd.adobe.edn |
| .emf |
application/x-emf |
.eml |
message/rfc822 |
| .ent |
text/xml |
.epi |
application/x-epi |
| .eps |
application/x-ps |
.eps |
application/postscript |
| .etd |
application/x-ebx |
.exe |
application/x-msdownload |
| .fax |
image/fax |
.fdf |
application/vnd.fdf |
| .fif |
application/fractals |
.fo |
text/xml |
| .frm |
application/x-frm |
.g4 |
application/x-g4 |
| .gbr |
application/x-gbr |
. |
application/x- |
| .gif |
image/gif |
.gl2 |
application/x-gl2 |
| .gp4 |
application/x-gp4 |
.hgl |
application/x-hgl |
| .hmr |
application/x-hmr |
.hpg |
application/x-hpgl |
| .hpl |
application/x-hpl |
.hqx |
application/mac-binhex40 |
| .hrf |
application/x-hrf |
.hta |
application/hta |
| .htc |
text/x-component |
.htm |
text/html |
| .html |
text/html |
.htt |
text/webviewhtml |
| .htx |
text/html |
.icb |
application/x-icb |
| .ico |
image/x-icon |
.ico |
application/x-ico |
| .iff |
application/x-iff |
.ig4 |
application/x-g4 |
| .igs |
application/x-igs |
.iii |
application/x-iphone |
| .img |
application/x-img |
.ins |
application/x-internet-signup |
| .isp |
application/x-internet-signup |
.IVF |
video/x-ivf |
| .java |
java/* |
.jfif |
image/jpeg |
| .jpe |
image/jpeg |
.jpe |
application/x-jpe |
| .jpeg |
image/jpeg |
.jpg |
image/jpeg |
| .jpg |
application/x-jpg |
.js |
application/x-javascript |
| .jsp |
text/html |
.la1 |
audio/x-liquid-file |
| .lar |
application/x-laplayer-reg |
.latex |
application/x-latex |
| .lavs |
audio/x-liquid-secure |
.lbm |
application/x-lbm |
| .lmsff |
audio/x-la-lms |
.ls |
application/x-javascript |
| .ltr |
application/x-ltr |
.m1v |
video/x-mpeg |
| .m2v |
video/x-mpeg |
.m3u |
audio/mpegurl |
| .m4e |
video/mpeg4 |
.mac |
application/x-mac |
| .man |
application/x-troff-man |
.math |
text/xml |
| .mdb |
application/msaccess |
.mdb |
application/x-mdb |
| .mfp |
application/x-shockwave-flash |
.mht |
message/rfc822 |
| .mhtml |
message/rfc822 |
.mi |
application/x-mi |
| .mid |
audio/mid |
.midi |
audio/mid |
| .mil |
application/x-mil |
.mml |
text/xml |
| .mnd |
audio/x-musicnet-download |
.mns |
audio/x-musicnet-stream |
| .mocha |
application/x-javascript |
.movie |
video/x-sgi-movie |
| .mp1 |
audio/mp1 |
.mp2 |
audio/mp2 |
| .mp2v |
video/mpeg |
.mp3 |
audio/mp3 |
| .mp4 |
video/mpeg4 |
.mpa |
video/x-mpg |
| .mpd |
application/vnd.ms-project |
.mpe |
video/x-mpeg |
| .mpeg |
video/mpg |
.mpg |
video/mpg |
| .mpga |
audio/rn-mpeg |
.mpp |
application/vnd.ms-project |
| .mps |
video/x-mpeg |
.mpt |
application/vnd.ms-project |
| .mpv |
video/mpg |
.mpv2 |
video/mpeg |
| .mpw |
application/vnd.ms-project |
.mpx |
application/vnd.ms-project |
| .mtx |
text/xml |
.mxp |
application/x-mmxp |
| .net |
image/pnetvue |
.nrf |
application/x-nrf |
| .nws |
message/rfc822 |
.odc |
text/x-ms-odc |
| .out |
application/x-out |
.p10 |
application/pkcs10 |
| .p12 |
application/x-pkcs12 |
.p7b |
application/x-pkcs7-certificates |
| .p7c |
application/pkcs7-mime |
.p7m |
application/pkcs7-mime |
| .p7r |
application/x-pkcs7-certreqresp |
.p7s |
application/pkcs7-signature |
| .pc5 |
application/x-pc5 |
.pci |
application/x-pci |
| .pcl |
application/x-pcl |
.pcx |
application/x-pcx |
| |
application/pdf |
|
application/pdf |
| .pdx |
application/vnd.adobe.pdx |
.pfx |
application/x-pkcs12 |
| .pgl |
application/x-pgl |
.pic |
application/x-pic |
| .pko |
application/vnd.ms-pki.pko |
.pl |
application/x-perl |
| .plg |
text/html |
.pls |
audio/scpls |
| .plt |
application/x-plt |
.png |
image/png |
| .png |
application/x-png |
.pot |
application/vnd.ms-powerpoint |
| .ppa |
application/vnd.ms-powerpoint |
.ppm |
application/x-ppm |
| .pps |
application/vnd.ms-powerpoint |
.ppt |
application/vnd.ms-powerpoint |
| .ppt |
application/x-ppt |
.pr |
application/x-pr |
| .prf |
application/pics-rules |
.prn |
application/x-prn |
| .prt |
application/x-prt |
.ps |
application/x-ps |
| .ps |
application/postscript |
.ptn |
application/x-ptn |
| .pwz |
application/vnd.ms-powerpoint |
.r3t |
text/vnd.rn-realtext3d |
| .ra |
audio/vnd.rn-realaudio |
.ram |
audio/x-pn-realaudio |
| .ras |
application/x-ras |
.rat |
application/rat-file |
| .rdf |
text/xml |
.rec |
application/vnd.rn-recording |
| .red |
application/x-red |
.rgb |
application/x-rgb |
| .rjs |
application/vnd.rn-realsystem-rjs |
.rjt |
application/vnd.rn-realsystem-rjt |
| .rlc |
application/x-rlc |
.rle |
application/x-rle |
| .rm |
application/vnd.rn-realmedia |
.rmf |
application/vnd.adobe.rmf |
| .rmi |
audio/mid |
.rmj |
application/vnd.rn-realsystem-rmj |
| .rmm |
audio/x-pn-realaudio |
.rmp |
application/vnd.rn-rn_music_package |
| .rms |
application/vnd.rn-realmedia-secure |
.rmvb |
application/vnd.rn-realmedia-vbr |
| .rmx |
application/vnd.rn-realsystem-rmx |
.rnx |
application/vnd.rn-realplayer |
| .rp |
image/vnd.rn-realpix |
.rpm |
audio/x-pn-realaudio-plugin |
| .rsml |
application/vnd.rn-rsml |
.rt |
text/vnd.rn-realtext |
| .rtf |
application/msword |
.rtf |
application/x-rtf |
| .rv |
video/vnd.rn-realvideo |
.sam |
application/x-sam |
| .sat |
application/x-sat |
.sdp |
application/sdp |
| .sdw |
application/x-sdw |
.sit |
application/x-stuffit |
| .slb |
application/x-slb |
.sld |
application/x-sld |
| .slk |
drawing/x-slk |
.smi |
application/smil |
| .smil |
application/smil |
.smk |
application/x-smk |
| .snd |
audio/basic |
.sol |
text/plain |
| .sor |
text/plain |
.spc |
application/x-pkcs7-certificates |
| .spl |
application/futuresplash |
.spp |
text/xml |
| .ssm |
application/streamingmedia |
.sst |
application/vnd.ms-pki.certstore |
| .stl |
application/vnd.ms-pki.stl |
.stm |
text/html |
| .sty |
application/x-sty |
.svg |
text/xml |
| .swf |
application/x-shockwave-flash |
.tdf |
application/x-tdf |
| .tg4 |
application/x-tg4 |
.tga |
application/x-tga |
| .tif |
image/tiff |
.tif |
application/x-tif |
| .tiff |
image/tiff |
.tld |
text/xml |
| .top |
drawing/x-top |
.torrent |
application/x-bittorrent |
| .tsd |
text/xml |
.txt |
text/plain |
| .uin |
application/x-icq |
.uls |
text/iuls |
| .vcf |
text/x-vcard |
.vda |
application/x-vda |
| .vdx |
application/vnd.visio |
.vml |
text/xml |
| .vpg |
application/x-vpeg005 |
.vsd |
application/vnd.visio |
| .vsd |
application/x-vsd |
.vss |
application/vnd.visio |
| .vst |
application/vnd.visio |
.vst |
application/x-vst |
| .vsw |
application/vnd.visio |
.vsx |
application/vnd.visio |
| .vtx |
application/vnd.visio |
.vxml |
text/xml |
| .wav |
audio/wav |
.wax |
audio/x-ms-wax |
| .wb1 |
application/x-wb1 |
.wb2 |
application/x-wb2 |
| .wb3 |
application/x-wb3 |
.wbmp |
image/vnd.wap.wbmp |
| .wiz |
application/msword |
.wk3 |
application/x-wk3 |
| .wk4 |
application/x-wk4 |
.wkq |
application/x-wkq |
| .wks |
application/x-wks |
.wm |
video/x-ms-wm |
| .wma |
audio/x-ms-wma |
.wmd |
application/x-ms-wmd |
| .wmf |
application/x-wmf |
.wml |
text/vnd.wap.wml |
| .wmv |
video/x-ms-wmv |
.wmx |
video/x-ms-wmx |
| .wmz |
application/x-ms-wmz |
.wp6 |
application/x-wp6 |
| .wpd |
application/x-wpd |
.wpg |
application/x-wpg |
| .wpl |
application/vnd.ms-wpl |
.wq1 |
application/x-wq1 |
| .wr1 |
application/x-wr1 |
.wri |
application/x-wri |
| .wrk |
application/x-wrk |
.ws |
application/x-ws |
| .ws2 |
application/x-ws |
.wsc |
text/scriptlet |
| .wsdl |
text/xml |
.wvx |
video/x-ms-wvx |
| .xdp |
application/vnd.adobe.xdp |
.xdr |
text/xml |
| .xfd |
application/vnd.adobe.xfd |
.xfdf |
application/vnd.adobe.xfdf |
| .xhtml |
text/html |
.xls |
application/vnd.ms-excel |
| .xls |
application/x-xls |
.xlw |
application/x-xlw |
| .xml |
text/xml |
.xpl |
audio/scpls |
| .xq |
text/xml |
.xql |
text/xml |
| .xquery |
text/xml |
.xsd |
text/xml |
| .xsl |
text/xml |
.xslt |
text/xml |
| .xwd |
application/x-xwd |
.x_b |
application/x-x_b |
| .sis |
application/vnd.symbian.install |
.sisx |
application/vnd.symbian.install |
| .x_t |
application/x-x_t |
.ipa |
application/vnd.iphone |
| .apk |
application/vnd.android.package-archive |
.xap |
application/x-silverlight-app |
38、網絡傳輸協議本質和作用是什么?
協議本質是雙方約定好的一種傳輸規則,為了讓傳輸數據的雙方節點能建立連接,按照約定去傳輸和解析數據
