Java后端學(xué)習(xí)筆記
術(shù)語
三者的關(guān)系:
JDK包含JRE睬捶,而JRE包含JVM姑食;
- Java開發(fā)工具包(JDK):
程序員在編寫Java程序時使用的軟件封救。
JDK的安裝目錄
1)bin
最主要的是JDK自帶的編譯器(javac.exe)政溃;
目前所有的IDE都有自己的編譯器艇劫,而不用JDK bin目錄中自帶的崩掘。所以七嫌,在安裝IDE時,你會發(fā)現(xiàn)它們只要求你選中JRE路徑就OK了苞慢。
2)include
Java和JVM交互用的頭文件诵原;
3)lib
類庫
4)jre(bin、lib)
Java運行時環(huán)境挽放;
jre/bin 中是 JVM绍赛,jre/lib 中是JVM工作所需的類庫;
總的來說辑畦,JDK用于Java程序的開發(fā)吗蚌,而JRE則是只能運行class源文件,而沒有編譯的功能纯出。
Java運行時環(huán)境(JRE):
僅僅有JVM還不能完成 .class類文件的執(zhí)行蚯妇,因為在解釋 .class的時候JVM需要調(diào)用解釋所需的類庫(存放在 jre/lib 中)。
JVM和 jre/lib 合起來就稱為 JRE潦刃。Java虛擬機(JVM):
它是整個Java實現(xiàn)跨平臺功能的核心侮措;
所有的Java程序,會首先被編譯為 .class 的類文件(這種類文件可以在 JVM 上執(zhí)行)乖杠。也就是說分扎,class類文件并不直接與機器的OS交互,而是經(jīng)過JVM間接的與OS交互胧洒,由JVM將程序解釋給本地系統(tǒng)來執(zhí)行畏吓。
JVM通過抽象OS和CPU結(jié)構(gòu),提供了一種與平臺無關(guān)的代碼執(zhí)行方法卫漫;不同的OS菲饼,JVM的具體實現(xiàn)也是互不相同的;JVM并不關(guān)心上層的Java源文件列赎,它只關(guān)注由源文件生成的 .class 類文件宏悦。Java SE、Java EE 和 Java ME
SE(Standard Edition):
用于桌面或簡單服務(wù)器應(yīng)用的Java平臺;
EE(Enterprise Edition):
用于復(fù)雜服務(wù)器應(yīng)用的Java平臺饼煞;
ME(Micro Edition):
用于手機和其它小型設(shè)備的Java平臺源葫;
設(shè)置JDK
Mac上安裝 Java JDK
1)下載JDK:Java SE - Downloads | Oracle Technology Network | Oracle
2)安裝JDK
雙擊 dmg 文件進行安裝;
測試JDK是否安裝成功:
javac
查看已安裝JDK的版本及路徑:
/usr/libexec/java_home -V
查看當前JDK版本:
java -version
3)卸載JDK
查看已安裝的JDK:
ls /Library/Java/JavaVirtualMachines/
僅僅刪除JDK:
sudo rm -rf /Library/Java/JavaVirtualMachines/jdk<version>.jdk
刪除JDK的插件plugins:
sudo rm -rf /Library/PreferencePanes/JavaControlPanel.prefPane
sudo rm -rf /Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin
sudo rm -rf /Library/LaunchAgents/com.oracle.java.Java-Updater.plist
sudo rm -rf /Library/PrivilegedHelperTools/com.oracle.java.JavaUpdateHelper
sudo rm -rf /Library/LaunchDaemons/com.oracle.java.Helper-Tool.plist
sudo rm -rf /Library/Preferences/com.oracle.java.Helper-Tool.plist
4)管理多版本JDK
修改系統(tǒng)環(huán)境變量:
- JAVA_HOME:JDK的安裝目錄砖瞧,它能夠使得其它相關(guān)環(huán)境變量的配置更加簡潔息堂。
- CLASSPATH:它的作用是告訴JRE,在哪些目錄下可以找到將要執(zhí)行的Java程序所需的類或包块促。
- PATH:將Java的bin加入到系統(tǒng)路徑中荣堰,這樣在命令行或其它程序就可以直接調(diào)用java、javac等命令了竭翠。
# 第一次配置
touch ~/.bash_profile
# 已配置過
vi ~/.bash_profile
# 設(shè)置相應(yīng)的JDK
# 設(shè)置 JDK8
export JAVA_8_HOME=`/usr/libexec/java_home -v 1.8`
# 設(shè)置 JDK10
export JAVA_10_HOME=`/usr/libexec/java_home -v 10`
# 設(shè)置默認 JDK(使用 JDK8)
export JAVA_HOME=$JAVA_8_HOME
export CLASSPATH=.:$JAVA_8_HOME/lib/tools.jar:$JAVA_8_HOME/lib/dt.jar
# alias 命令動態(tài)切換 jdk 版本
alias JDK_8="export JAVA_HOME=$JAVA_8_HOME ; export CLASSPATH=.:$JAVA_8_HOME/lib/tools.jar:$JAVA_8_HOME/lib/dt.jar"
alias JDK_X="export JAVA_HOME=$JAVA_10_HOME"
刷新環(huán)境變量振坚,并查看當前的JDK版本:
source ~/.bash_profile
java -version
5)使用命令行編譯并運行Java程序
public class FirstApp
{
public static void main(String[] args)
{
System.out.println("My first Java app!");
}
}
編譯并運行
javac FirstApp.java
java FirstApp
- javac 程序是一個Java編譯器。它將 .java 源文件編譯成 .class 目標文件
- java 程序啟動 JVM逃片,JVM執(zhí)行編譯器放在 .class 目標文件中的字節(jié)碼
Tomcat for Mac 的下載與安裝
- 下載:Apache Tomcat? - Welcome!
- 安裝:
1)解壓包屡拨,然后將它放入 “/Users/計算機名/Library/…” 目錄下,并重命名為 ApacheTomcat(為了之后配置更方便)褥实;
或者
不修改默認的目錄名呀狼,而是創(chuàng)建 Tomcat 目錄,然后在該目錄下創(chuàng)建一個軟鏈接
ln -s apache-tomcat-x.x.x Home
這樣损离,就可以輕松的用 /Library/Tomcat/Home 去訪問 tomcat 了哥艇。這種做法的好處是,如果以后 tomcat 有了新版本僻澎,就直接將 Home 指向新版本即可貌踏,其它有關(guān) tomcat 路徑引用的配置不需要修改。
2)啟動Tomcat
cd /Users/計算機名/Library/ApacheTomcat/bin
./startup.sh
或者
cd /Users/計算機名/Library/Tomcat/Home/bin
./startup.sh
如果出現(xiàn) “Tomcat started” 窟勃,說明Tomcat啟動成功祖乳;
如果出現(xiàn) “-bash: ./startup.sh: Permission denied”,需要修改權(quán)限
chmod u+x ./*.sh
指令解析:
u 文件所有者
+x 添加可執(zhí)行權(quán)限
./ 當前目錄
*.sh 所有.sh文件
3)驗證安裝是否成功
在瀏覽器地址欄輸入:http://localhost:8080秉氧,顯示如下界面眷昆,說明安裝成功:
[image:43BD1F00-15AB-481D-B8DA-B4B263D77B38-33499-000098C37CC7D32E/屏幕快照 2018-06-06 上午11.00.48.png]
如果出現(xiàn) “Tomcat started”,但是無法訪問 http://localhost:8080汁咏,那么需要重啟 tomcat亚斋。
必須先 shutdown
./shutdown.sh
然后再 startup
./startup.sh
4)關(guān)閉Tomcat
./shutdown.sh
5)查看Tomcat版本信息
sh catalina.sh version
6)Tomcat目錄結(jié)構(gòu)
- bin:存放Tomcat命令
- conf:存放Tomcat配置信息(server.xml是核心的配置文件)
- lib:支持Tomcat軟件運行的jar包和技術(shù)支持包(如 Servlet和JSP)
- logs:日志信息
- temp:臨時目錄
- webapps:共享資源文件和web應(yīng)用目錄
- work:Tomcat的運行目錄(JSP運行時產(chǎn)生的臨時文件就存放在這里)
7)修改端口號
服務(wù)器的默認端口是8080;
為了避免與系統(tǒng)端口沖突攘滩,必須設(shè)置1024以上的端口號帅刊,如 8888
cd /Users/計算機名/Library/ApacheTomcat/conf
mvim server.xml
或者
cd /Users/計算機名/Library/Tomcat/Home/conf
mvim server.xml
找到 <Connector port="8080"... 修改 port="8080" 為 8888
重啟服務(wù)器,設(shè)置生效
8)用戶名漂问、密碼設(shè)置
cd /Users/計算機名/Library/ApacheTomcat/conf
mvim tomcat-users.xml
或者
cd /Users/計算機名/Library/Tomcat/Home/conf
mvim
在</tomcat-users>中添加如下代碼:
<role rolename="manager-gui"/>
<user username="admin" password="1234qwer" roles="manager-gui"/>
重啟服務(wù)器赖瞒,設(shè)置生效
重新打開 http://localhost:8080 到Tomcat主界面,點擊 Manager App 等按鈕女揭,輸入賬號和密碼,即可登陸Tomcat
IDEA進行Java開發(fā)配置
1)IntelliJ IDEA 版本比較和區(qū)別:
- Ultimate:For web and enterprise development
- Community:For JVM and Android development
2)配置JDK
Configure -> Project Defaults -> Project Structure
New新建Mac上已安裝的JDK
3)IDEA創(chuàng)建javaWeb項目步驟
- Create New Project
[image:C1FCAD18-E642-4493-A50F-4BD7DD33609A-33499-0000B1A411B735E2/屏幕快照 2018-06-07 上午9.39.48.png]
選擇對應(yīng)的Project SDK冒黑,然后勾選 Web Application田绑,點擊 Next - 自定義修改對應(yīng)的工程名和路徑等
[image:DCCDC5B9-2F6A-4055-803C-276615A0BC8C-33499-0000B1CDD29B3E6F/屏幕快照 2018-06-07 上午9.42.23.png] - 優(yōu)化項目的層次結(jié)構(gòu)
[image:378104DF-E5F3-4637-8C29-2AD9A7642A8B-33499-0000B1F52F38EA3A/屏幕快照 2018-06-07 上午9.46.00.png]
WEB-INF文件夾下勤哗,分別創(chuàng)建 classes 和 lib 兩個文件夾抡爹;
其中,classes 用于存放編譯后輸出的 .class 文件芒划, lib 用于存放第三方j(luò)ar包冬竟。 - 配置class文件存放的路徑
[image:936C43F2-0B6E-44EA-A17E-9E75AFEDAF43-33499-0000B24638910952/屏幕快照 2018-06-07 上午9.49.48.png]
[image:9CF5690A-B7BD-4DC6-A5AE-CEFD5A1EC8BC-33499-0000B24939401DBE/屏幕快照 2018-06-07 上午9.50.28.png]
[image:6A65997D-5DA4-4A67-A4AC-F42F346184E9-33499-0000B24B26390AB5/屏幕快照 2018-06-07 上午9.51.18.png]
“Use module compile output path” 中,修改path為 WEB-INF 中創(chuàng)建的 classes 文件夾路徑民逼; - 配置lib文件存放的路徑
[image:2CF1F7F3-2AB6-4676-A93A-20A68697B3EA-33499-0000B27EB1D36B64/屏幕快照 2018-06-07 上午9.55.41.png]
[image:C01183BD-6293-4FED-9156-6778020C73E8-33499-0000B2986604BD9D/屏幕快照 2018-06-07 上午9.56.59.png]
[image:3E885D0D-4EA6-4166-93C7-DD0F35A0D346-33499-0000B29A9BC67B5E/屏幕快照 2018-06-07 上午9.57.14.png]
Modules -> Dependencies -> + JARs or directories -> 選擇WEB-INF中創(chuàng)建的lib文件夾 -> Jar Directory -> 完成
4)IDEA中配置本地服務(wù)器(Tomcat)
- 點擊 Edit Configurations...
[image:AE7A386C-97B8-4DBF-A5BD-D204A8D44643-33499-0000B3161EBA08CE/屏幕快照 2018-06-07 上午10.05.39.png] - 添加 Tomcat 本地服務(wù)器
[image:19508F1F-CDAA-416A-AE22-E95C3A52882C-33499-0000B32551C68130/屏幕快照 2018-06-07 上午10.07.31.png] - 修改本地Tomcat名字泵殴、配置Tomcat路徑
[image:AC90A821-4C2A-4367-BCDE-ACE51A9D342F-33499-0000B344F7855C4D/屏幕快照 2018-06-07 上午10.09.03.png] - 添加 Artifact…
[image:C991AA5D-C0F5-414E-A285-72F2D2EED74D-33499-0000B35AFD329318/屏幕快照 2018-06-07 上午10.11.22.png] - 修改index.jsp并運行
[image:A5819D51-74ED-48BE-94FB-AB14AA2CCC4D-33499-0000B37D535911C2/屏幕快照 2018-06-07 上午10.14.07.png]
::注意:在啟動WebApp之前,一定要先關(guān)閉本地配置的Tomcat服務(wù)器拼苍,否則會出現(xiàn)端口號被占用的警告笑诅,導(dǎo)致無法顯示期望的界面!::
[image:185EF565-F92B-488D-8616-7A8A46F0E107-33499-0000B3B8F8E86860/屏幕快照 2018-06-07 上午10.17.01.png]
構(gòu)建并運行applet(過去的記憶)
JavaApplet 就是用 Java 編寫的小應(yīng)用程序疮鲫,可以直接嵌入到網(wǎng)頁中吆你,并能夠產(chǎn)生特殊的效果。
Applet的工作原理:
含有Applet的網(wǎng)頁的HTML文件源代碼中帶有<applet> 和</applet>這樣一對標記俊犯。當支持Java的網(wǎng)絡(luò)瀏覽器遇到這對標記時妇多,就將下載相應(yīng)的小應(yīng)用程序代碼并在本地計算機上執(zhí)行該Applet。
Java的基本程序設(shè)計結(jié)構(gòu)
一個簡單的Java應(yīng)用程序
public class FirstSample
{
public static void main(String[] args)
{
System.out.println("Hello, World!");
}
}
- 程序分析
1)Java區(qū)分大小寫燕侠;
2)關(guān)鍵詞 public(訪問修飾符 access modifier):
用于控制程序的其它部分對這段代碼的訪問級別者祖;
延伸學(xué)習(xí):public、protected绢彤、default 和 private
3)關(guān)鍵字 class:
表明Java程序中的全部內(nèi)容都必須包含在類中七问;
這里,只需將 類 作為一個加載程序邏輯的容器茫舶,程序邏輯定義了應(yīng)用程序的行為械巡。
4)Java中類的命名規(guī)則:
必須字母開頭,字母和數(shù)字的任意組合奇适;
標準的類命名規(guī)范是采用 CamelCase(駱駝命名法)坟比。
5)Java中,源代碼的文件名必須與公共類的名字相同嚷往,并用 .java 作為擴展名(注意葛账,一定注意大小寫)。
6)編譯 FirstSample.java 源文件:
javac FirstSample.java
編譯后皮仁,會得到一個包含這個類字節(jié)碼的目標文件 FirstSample.class
運行 FirstSample 程序:
java FirstSample
注意:請記住籍琳,不要添加 .class 擴展名菲宴!
7)根據(jù)Java語言規(guī)范,main() 方法必須聲明為 public
請記浊骷薄:每個Java應(yīng)用程序都必須有一個main方法喝峦,其聲明格式如下:
public class /ClassName/
{
public static void main(String[] args)
{
/program statements/
}
}
8)大括號 { } 的使用規(guī)則:
Java中,習(xí)慣于把匹配的大括號上下對齊呜达。
9)關(guān)鍵字 static
方便于在沒有創(chuàng)建任何對象的前提下谣蠢,僅僅通過類本身來調(diào)用 static (靜態(tài))方法/變量。
在 static 方法內(nèi)部查近,不能調(diào)用非靜態(tài)方法/變量眉踱,反過來是可以的。
10)使用 System.out 對象霜威,并通過 (.)調(diào)用了它的 println 方法谈喳。
11)Java中的3種注釋
單行注釋: //
多行注釋: /* 和 / (注釋不能嵌套)
自動生成文檔注釋: 以 /* 開始,以 */ 結(jié)束
Java數(shù)據(jù)類型
1)Java是強類型語言(意味著必須為變量聲明類型)戈泼;
2)Java中的8種基本類型(primitive type):
- 整型(int 4婿禽、short 2、long 8 和 byte 1)
- 通常使用 int 和 long大猛,short 和 byte 類型主要用于特定的應(yīng)用場合扭倾;
- ::在Java中,整型的范圍與運行Java代碼的機器無關(guān)胎署。(這就解決了軟件從一個平臺移植到另一平臺吆录,或者在同一平臺中的不同OS之間進行移植給程序員帶來的諸多問題)::
- 注意,Java中沒有任何無符號(unsigned)形式的整型琼牧;
- 浮點類型(float 4恢筝、double 8)
- 很多情況下,float 類型的精度不能滿足實際需求巨坊。所以撬槽,一般都采用double 類型;(float 類型用后綴 F/f 標識趾撵,double 用 D/d 或 缺手度帷)
- 用于表示溢出和出錯的三個特殊浮點數(shù)值:
正無窮大 Double.POSITIVE_INFINITY
負無窮大 Double.NEGATIVE_INFINITY
NaN Double.NaN
::特別說明,不能通過 if(x == Double.NaN) 的方式來檢測一個特定值是否等于 Double.NaN 占调;而需要使用 if (Double.isNaN(x)) 方法暂题。::
- 字符類型char(用于表示Unicode編碼的字符單元)
- 之前,char類型用于表示單個字符究珊;如今薪者,有一些Unicode字符需要用兩個char值來描述。
- char 類型的值可以表示為十六進制值剿涮,范圍從 \u0000 ~ \uffff言津;
::警告攻人,Unicode轉(zhuǎn)義序列會在解析代碼之前得到處理。::
如:”\u0022+\u0022” 并不會得到字符串 ““+””悬槽,而是會得到一個空串“”怀吻。
::注意,一定要注意注釋中的 \u::
如:// \u000d is a newline 會產(chǎn)生語法錯誤(\u000d 會替換成換行符)初婆。 - 我們強烈建議不要在程序中使用char類型E钇隆!烟逊!
- boolean類型(false渣窜、true)
整數(shù)值和布爾值之間不能進行相互轉(zhuǎn)換(C++中是可以的);
if (x = 0) {} // 不能通過編譯(整數(shù)表達式 x = 0 不能轉(zhuǎn)換為布爾值)
變量
1)不提倡在一行中聲明多個變量宪躯;
int i, j; // 不提倡
2)聲明一個變量之后,必須用賦值語句對變量進行顯式初始化位迂;
::在Java中访雪,不區(qū)分變量的聲明與定義;::
// C/C++
int i = 10; // 定義
extern int i; // 聲明
常量
1)Java中掂林,使用關(guān)鍵字final指示常量臣缀;習(xí)慣上,常量名使用全大寫泻帮。
final double CM_PER_INCH = 2.54;
2)類常量(可以在一個類中的多個方法中使用):static final
public class Sample
{
public static final double CM_PER_INCH = 2.54;
public static void main(String[] args)
{
System.out.println("1 inch is " + CM_PER_INCH + "cm");
}
}
運算符
注意精置,整數(shù)被0除,將會產(chǎn)生一個異常锣杂;而浮點數(shù)被0除將會得到無窮大或NaN結(jié)果脂倦。
100/0; // 異常
88.8/0; // 無窮大 或 NaN
數(shù)學(xué)函數(shù)
- Math類函數(shù)
如:floorMod
import static java.lang.Math.*;
public class FirstApp
{
public static void main(String[] args)
{
int result = (-5)%2;
System.out.println("(-5)%2 is equal: " + result);
int fmResult = floorMod(-5, 2);
System.out.println("Math.floorMod(-5, 2) is equal: " + fmResult);
}
}
強制類型轉(zhuǎn)換
::警告:如果試圖將一個數(shù)值做強制類型轉(zhuǎn)換,而又超出了目標類型的表示范圍元莫,結(jié)果將會被截斷成一個不同的值赖阻。::
::如:(byte)300 的實際值為 44::
關(guān)系運算符和位運算符
1)==、踱蠢!=火欧、>、<=茎截、&&苇侵、|| 、企锌!和 三元操作符 ? :
其中榆浓,&& 和 || 是按照“短路”方式求值的(也就是,如果第一個操作已確定表達式的值霎俩,那么就不計算第二個操作數(shù)了)哀军;
2)&沉眶、|、^ 和 ~
::注意杉适,當位運算符 & 和 | 應(yīng)用在boolean上時谎倔,不采用“短路”方式求值。(也就是說猿推,得到計算結(jié)果之前片习,兩個操作數(shù)都需要計算)::
3)>>、<< 和 >>> 移位運算符
::警告:移位運算符的右操作數(shù)要完成 模32 的運算(如果左操作數(shù)是long型蹬叭,需要對右操作數(shù)做 模64 運算)藕咏。::
如:1 << 35 的值等同于 1 << 3,也就是 8
::>> 和 >>> 的區(qū)別:::
::>>> 運算符用0填充高位秽五,而 >> 用符號位填充高位孽查。::
字符串
1)Java沒有內(nèi)置的字符串類型,而是在標準Java類庫中提供了一個預(yù)定義類
String nilStr = ""; // 空串
String greeting = "Hello String!";
String subS = greeting.subString(0, 3); // "Hel"
// 注意坦喘,subString方法的第二個參數(shù)表示盲再,不想復(fù)制的第一個位置。
2)拼接字符串
當將一個字符串與一個非字符串的值進行拼接時瓣铣,后者被轉(zhuǎn)換成字符串(任何一個Java對象都可以轉(zhuǎn)換成字符串)答朋。
int age = 30;
String rating = "PG" + age;
String all = String.join(" /", "N", "B", "A");
// 輸出:"N /B /A"
3)字符串比較
注意,一定不要使用 == 運算符檢測兩個字符串是否相等棠笑。
s1.equals(s2)
"Hello".equals(greeting)
"Hello".equalsIgnoreCase("hello")
4)空串”” 和 null串
// 判斷空串
if (str.length() == 0)
// 或
if (str.equals(""))
// 判斷null串
if (str == null)
5)構(gòu)建字符串
采用字符串拼接的方式梦碗,效率比較低(因為每次連接字符串,都會構(gòu)建一個新的String對象)蓖救。
StringBuilder builder = new StringBuilder();
builder.append("abc");
builder.append("XYZ");
String completedStr = builder.toString();
System.out.println(completedStr); // abcXYZ
6)String API
輸入輸出
- 讀取輸入
1)構(gòu)造 Scanner 對象:
import java.util.*;
// 構(gòu)造 Scanner 對象洪规,并與“標準輸入流” System.in 關(guān)聯(lián)
Scanner in = new Scanner(System.in);
// 使用 nextLine() 方法,是因為在輸入行中可以包含空格藻糖;
// 如果想要讀取一個單詞(以空白符為分隔符)淹冰,可使用 next() 方法;
System.out.print("What is your name? ");
String name = in.nextLine();
// 讀取整數(shù) nextInt()巨柒;
// 讀取浮點數(shù) nextDouble()樱拴;
System.out.print("How old are you? ");
int age = in.nextInt();
System.out.println("Hello " + name + ". Next year, you'll be " + (age + 1));
注意,Scanner 類的輸入是可見的洋满,所以不適用于從控制臺讀取密碼晶乔。
2)Console 類
import java.io.Console;
Console cons = System.console();
String username = cons.readLine("User name: ");
char[] passwd = cons.readPassword("Password: ");
cons.printf("username is %s and password is %s\n", username, String.valueOf(passwd));
::為了安全起見,返回的密碼存放在一維字符數(shù)組中牺勾,而不是字符串中正罢。::
::在對密碼進行處理后,應(yīng)該馬上用一個填充值覆蓋數(shù)組元素驻民。::
Console 和 Scanner 類比較:Console類每次只能讀取一行輸入翻具,而沒有能夠去讀一個單詞或一個數(shù)值的方法履怯。
- 格式化輸出
System.out.printf();
::注釋,可以使用 %s 轉(zhuǎn)換符格式任意的對象裆泳。::
使用String類的靜態(tài)方法 String.format 來創(chuàng)建一個格式化的字符串:
String message = String.format("Hello, %s.\nNext year, you'll be %d", name, age);
- 文件輸入與輸出
略
控制流程
::Java中的控制流程叹洲,沒有g(shù)oto語句,但是 break 語句可以帶標簽工禾。::
- 塊(block)作用域
1)塊block 是指用 {} 括起來的若干條Java語句运提;
2)塊 確定了變量的作用域;
3)塊 可以嵌套闻葵;
::警告民泵,不能在嵌套的 塊block 中聲明同名的變量(C++ 中可以)。::
public static void main()
{
int n = 2;
...
{
int n = 4; // Error: redefine n in inner block
...
}
}
- 條件語句
if (/condition/)
{
/statement1/
...
}
else
/statement/
- 循環(huán)
while (/condition/) /statement/
// or
do /statement/ while (/condition/);
// or
for (;;)
{
/statement1/
...
}
// or 通用for循環(huán)(for each循環(huán))
for (/variable/ : /collection/)
{
/statement/
}
- 多重選擇:switch語句
switch (/tag/)
{
case /value1/:
...
break;
case /value2/:
...
break;
default:
...
break;
}
case標簽tag的類型:
1)char槽畔、byte栈妆、short或int等常量表達式;
2)枚舉常量竟痰;
3)字符串字面量签钩;
大數(shù)值
- BigInteger:實現(xiàn)了任意精度的整數(shù)運算。
// valueOf() 靜態(tài)方法
BigInteger a = BigInteger.valueOf(100);
// + 和 * 算數(shù)運算的實現(xiàn)
BigInteger b = BigInteger.valueOf(a+10);
BigInteger c = a.add(b); // c = a+b
BigInteger d = c.multiply(a.add(b)); // d = c*(a+b)
- BigDecimal:實現(xiàn)了任意精度的浮點數(shù)運算。
略
數(shù)組
- 數(shù)組的聲明與創(chuàng)建
int[] a; // 推薦
// 或
int a[];
// 創(chuàng)建
int[] a = new int[100];
數(shù)組創(chuàng)建成功后,不同類型的數(shù)組眠寿,會有不同的初始化值:
1)數(shù)字數(shù)組 -> 0
2)boolean數(shù)組 -> false
3)對象數(shù)組 -> null
String[] names = new String[10]; // 所有字符串都為null
::數(shù)組一旦創(chuàng)建躬柬,就不能在改變它的大小(可以改變每個數(shù)組的元素)拾给。::
::如果需要擴展數(shù)組的大小祥得,需要使用 -> 數(shù)組列表(array list)::
- for each 循環(huán):循環(huán)變量將會遍歷數(shù)組中的每一個元素,而不需要使用下標蒋得。
for (String element : names)
System.out.println(element);
- 數(shù)組初始化及匿名數(shù)組
int[] smallPrimes = {1, 5, 3, 9};
// 匿名數(shù)組
smallPrimes = new int[] {2, 8, 10, 4}; // 這種語法形式可以在不創(chuàng)建新變量的情況下重新初始化一個數(shù)組
::Java中级及,允許數(shù)組長度為0。這在編寫一個返回值為數(shù)組的方法额衙,結(jié)果恰巧為空時饮焦,非常有用!::
new elementType[0];
- 數(shù)組拷貝
1)直接拷貝(兩個變量引用同一數(shù)組)
int[] smallPrimes = {1, 3, 5, 7};
int[] luckyNumbers = smallPrimes;
luckyNumbers[1] = 4; // 現(xiàn)在 smallPrimes[1] 也是 4
System.out.printf("luckyNumbers[1] is %d, smallPrimes[1] is %d.\n", luckyNumbers[1], smallPrimes[1]);
2)使用Arrays類的copyOf靜態(tài)方法
int[] smallPrimes = {1, 3, 5, 7};
int[] luckyNumbers = Arrays.copyOf(smallPrimes, smallPrimes.length);
luckyNumbers[1] = 4; // 現(xiàn)在 smallPrimes[1] 依舊是 3
- 多維數(shù)組
// 聲明
int[][] magicSquare;
// 初始化
magicSquare = new int[2][3];
// 聲明并初始化
int[][] magicSquare =
{
{1, 2, 3},
{7, 8, 9},
};
- 不規(guī)則數(shù)組:數(shù)組的每一行有不同的長度窍侧。
::Java實際上沒有多維數(shù)組县踢,只有一維數(shù)組。多維數(shù)組被解釋為“數(shù)組的數(shù)組”::
for (int i = 0; i < odds.length; i++)
for (int j = 0; j < odds[i].length; j++)
{
...
odds[i][j] = x;
}
對象與類
Web基礎(chǔ)
Http協(xié)議
- HTTP簡介
1)HTTP(Hyper Text Transfer Protocol)
用于從WWW服務(wù)器傳輸超文本到本地瀏覽器的傳輸協(xié)議伟件。
2)
HTTP是基于 TCP/IP 通信協(xié)議來傳遞數(shù)據(jù)硼啤;
HTTP是一個屬于應(yīng)用層的面向?qū)ο髤f(xié)議;
HTTP協(xié)議工作于 客戶端-服務(wù)器(C-S) 架構(gòu)上斧账; - HTTP主要特點
1)簡單快速:C -> S 請求服務(wù)時谴返,只需傳送“請求方法”和“路徑”(如:GET煞肾、POST、HEAD等嗓袱,每種方法規(guī)定了C和S間不同的聯(lián)系類型)籍救。
2)靈活:HTTP允許傳送任意類型的數(shù)據(jù)對象(類型由 Content-Type 標記)。
3)無連接:無連接的含義是索抓,限制每次連接只處理一個請求(S處理完C的請求钧忽,并收到C的應(yīng)答后,立即斷開連接)逼肯。
4)無狀態(tài):HTTP協(xié)議是無狀態(tài)協(xié)議耸黑。 - HTTP之URL
1)HTTP使用 URI(Uniform Resource Identifiers)統(tǒng)一資源標識符 來傳輸數(shù)據(jù)和建立連接。
2)URL(Uniform Resource Locator)統(tǒng)一資源定位符 是一種特殊類型的 URI篮幢,包含了用于查找某個資源的足夠信息大刊。
3)分析URL:
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
協(xié)議部分:“http:” (常見協(xié)議還有 FTP、HTTPS等)三椿; “//”是分隔符缺菌。
域名部分:“www.aspxfans.com” (也可使用IP地址作為域名使用)。
端口部分:跟在域名后的就是端口(域名和端口號之間用 “:” 分割)搜锰;端口不 是URL中必須的伴郁,如果缺省,將采用默認端口蛋叼。
虛擬目錄部分:從域名后第一個 “/” 開始到最后一個 “/” 為止(可缺屎父怠)。
文件名部分:從域名后的最后一個 “/” 開始到 “?” 為止(可缺时蜂獭)狐胎;如果沒有 “?”,那么到 “#” 為止歌馍;如果都沒有握巢,那么到結(jié)束,都是文件名部 分松却。
參數(shù)部分:從 “?” 開始到 “#” 為止暴浦,之間的部分都是參數(shù)部分(參數(shù)之間用 “&” 分割)。
錨部分:從 “#” 開始到最后玻褪,都是錨部分肉渴。
- HTTP之請求消息Request
[image:20CBD126-E11A-45C7-9F53-8285DE7C240C-33499-0000E7906F29D35F/2964446-fdfb1a8fce8de946.png]
POST請求例子(使用Charles抓取的request):
POST / HTTP1.1
Host:www.wrox.com
User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)
Content-Type:application/x-www-form-urlencoded
Content-Length:40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
請求行:用來表明請求類型,訪問的資源以及使用的HTTP版本带射。
請求頭:用來說明服務(wù)器要使用的附加信息同规。
空行:請求頭后面的空行是必須的。
請求數(shù)據(jù):也叫主體,可以添加任意數(shù)據(jù)券勺。
- HTTP之響應(yīng)消息Response
[image:25FC2229-9FA7-4E43-A3F0-15FF3461BCE0-33499-0000E80F450B99B3/2964446-1c4cab46f270d8ee.jpg]
HTTP響應(yīng)例子:
HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT
Content-Type: text/html; charset=UTF-8
<html>
<head></head>
<body>
<!--body goes here-->
</body>
</html>
狀態(tài)行:由 HTTP協(xié)議版本號绪钥,狀態(tài)碼,狀態(tài)消息 三部分組成关炼。
消息報頭:用來說明客戶端要使用的一些附加信息程腹。
空行:消息報頭后的空行是必須的。
響應(yīng)正文:服務(wù)器返回給客戶端的文本信息儒拂。
- HTTP之狀態(tài)碼
1xx:指示信息 -> 表示請求已接收寸潦,繼續(xù)處理
2xx:成功 -> 表示請求已被成功接收、理解社痛、接受
3xx:重定向 -> 要完成請求必須進行更進一步的操作
4xx:客戶端錯誤 -> 請求有語法錯誤或請求無法實現(xiàn)
5xx:服務(wù)器端錯誤 -> 服務(wù)器未能實現(xiàn)合法的請求
常見狀態(tài)碼:
200 OK //客戶端請求成功
400 Bad Request //客戶端請求有語法錯誤见转,不能被服務(wù)器所理解
401 Unauthorized //請求未經(jīng)授權(quán),這個狀態(tài)代碼必須和WWW-Authenticate報頭域一起使用
403 Forbidden //服務(wù)器收到請求蒜哀,但是拒絕提供服務(wù)
404 Not Found //請求資源不存在斩箫,eg:輸入了錯誤的URL
500 Internal Server Error //服務(wù)器發(fā)生不可預(yù)期的錯誤
503 Server Unavailable //服務(wù)器當前不能處理客戶端的請求,一段時間后可能恢復(fù)正常
- HTTP請求方法
GET 請求指定的頁面信息撵儿,并返回實體主體乘客。
HEAD 類似于get請求,只不過返回的響應(yīng)中沒有具體的內(nèi)容淀歇,用于獲取報頭
POST 向指定資源提交數(shù)據(jù)進行處理請求(例如提交表單或者上傳文件)易核。數(shù)據(jù)被包含在請求體中。POST請求可能會導(dǎo)致新的資源的建立和/或已有資源的修改浪默。
PUT 從客戶端向服務(wù)器傳送的數(shù)據(jù)取代指定的文檔的內(nèi)容耸成。
DELETE 請求服務(wù)器刪除指定的頁面。
CONNECT HTTP/1.1協(xié)議中預(yù)留給能夠?qū)⑦B接改為管道方式的代理服務(wù)器浴鸿。
OPTIONS 允許客戶端查看服務(wù)器的性能。
TRACE 回顯服務(wù)器收到的請求弦追,主要用于測試或診斷岳链。
- HTTP工作原理
1)HTTP協(xié)議 定義了Web客戶端如何從Web服務(wù)器請求Web頁面,以及服務(wù)器如何把Web頁面?zhèn)魉徒o客戶端劲件。
2)HTTP協(xié)議 采用了 請求/響應(yīng) 模型掸哑。
3)HTTP 請求/響應(yīng) 步驟:
1. 客戶端連接到Web服務(wù)器
一個HTTP客戶端(通常是瀏覽器),向Web服務(wù)器請求解析URL中的域名對應(yīng)的IP地址零远;然后根據(jù)IP地址和HTTP端口(默認是80)建立一個TCP套接字連接苗分。
2. 發(fā)送HTTP請求
通過TCP套接字,客戶端向Web服務(wù)器發(fā)送一個請求報文(一個請求報文 由 請求行牵辣、請求頭摔癣、空行 和 請求數(shù)據(jù) 4部分組成)。
3. 服務(wù)器接收請求并返回HTTP響應(yīng)
Web服務(wù)器解析請求,定位請求資源择浊。服務(wù)器將資源復(fù)本寫到TCP套接字戴卜,由客戶端讀取(一個響應(yīng) 由 狀態(tài)行琢岩、響應(yīng)頭部投剥、空行 和 響應(yīng)數(shù)據(jù) 4部分組成)。
4. 釋放TCP連接
如果 connection 模式為 close担孔,則服務(wù)器主動關(guān)閉TCP連接江锨,客戶端被動關(guān)閉連接,釋放TCP連接糕篇;
如果 connection 模式為 keepalive啄育,則該連接會保持一段時間,在該時間段內(nèi)娩缰,可以繼續(xù)接收請求灸撰。
5. 客戶端瀏覽器解析HTML內(nèi)容
客戶端首先解析狀態(tài)行,查看表明HTTP請求成功與否的狀態(tài)代碼拼坎;
然后解析每一個響應(yīng)頭浮毯。
- GET和POST請求的區(qū)別
GET請求:
GET /books/?sex=man&name=Professional HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
::注意,最后一行是空行::
POST請求:
POST / HTTP/1.1
Host: www.wrox.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
1)
GET提交泰鸡,請求的數(shù)據(jù)會附在URL之后(就是把數(shù)據(jù)放在 HTTP協(xié)議頭中)债蓝,用 “?” 分割URL和傳輸?shù)臄?shù)據(jù),參數(shù)間用 “&” 連接盛龄;
POST提交饰迹,請求的數(shù)據(jù)放置在HTTP的請求主體中;
::因此余舶,GET提交的數(shù)據(jù)會在地址欄中顯示啊鸭,而POST提交不會。::
2)傳輸數(shù)據(jù)的大心渲怠:
::首先聲明赠制,HTTP協(xié)議沒有對傳輸?shù)臄?shù)據(jù)大小進行限制,也沒有對URL長度進行限制挟憔。::
在實際的開發(fā)中钟些,URL和傳輸數(shù)據(jù)的大小都存在限制。
GET:特定瀏覽器和服務(wù)器對URL長度有限制
POST:Web服務(wù)器會規(guī)定對post提交的數(shù)據(jù)大小進行限制
3)
GET:方式通過Request.QueryString來取得變量的值绊谭;
POST:方式通過Request.Form來獲取變量的值政恍。
4)安全性:
POST的安全性高于GET。
比如达传,通過GET提交數(shù)據(jù)篙耗,用戶名和密碼會將明文顯示在URL上
5)get迫筑、post和soap
get:請求參數(shù)是作為一個key/value對的序列(查詢字符串)附加到URL上,并且查詢字符串的長度受到Web瀏覽器和服務(wù)器的限制鹤树。因此铣焊,不適合傳輸大型數(shù)據(jù)集,同時它很不安全罕伯。
Post:請求參數(shù)放置在請求主體中曲伊,因此必須將Content-type設(shè)置為application/x-www-form-urlencoded。它不支持復(fù)雜數(shù)據(jù)類型追他。
Soap:post請求的一個專用版本坟募,遵循一種特殊的xml消息格式。因此邑狸,Content-type設(shè)置為: text/xml懈糯,任何數(shù)據(jù)都可以xml化。
HTTP協(xié)議定義了很多與服務(wù)器交互的方法单雾,最基本的有:
GET赚哗、POST、PUT和DELETE
一個URL地址用于描述網(wǎng)絡(luò)上的一個資源硅堆,而HTTP中GET屿储、POST、PUT渐逃、DELETE分別對應(yīng)著對這個資源的 查够掠、改、增茄菊、刪 4個操作疯潭。
::GET一般用于 獲取/查詢 資源信息;而POST一般用于更新資源信息面殖。::
TCP協(xié)議詳解
- TCP/IP協(xié)議的由來
在世界各地竖哩,每臺電腦運行著各自不同的操作系統(tǒng)為我們服務(wù),它們在表達同一信息的時候所使用的方法千差萬別脊僚。
這就好像圣經(jīng)中期丰,上帝打亂了世界各地人的口音,讓彼此無法正常合作一樣吃挑。
于是,人們就想方設(shè)法的將電腦連接到了一起街立。
但是舶衬,簡單的將電腦連接到一起還遠遠不夠,就好像語言不通的兩個人見面了赎离,也同樣是不能交流信息逛犹。
TCP/IP因此而生。
TCP/IP不是一個協(xié)議,而是一個協(xié)議族的統(tǒng)稱虽画。
TCP/IP協(xié)議分層
[image:E33A019E-9340-4525-9892-9E87F66199D3-33499-0000F201CA36F783/2964446-1fd7a0f3216c0530.jpg]
1)應(yīng)用層:向用戶提供了一組常用的應(yīng)用程序舞蔽。
2)傳輸層:提供應(yīng)用程序間的通信。
功能:
一码撰、格式化信息流
二渗柿、提供可靠傳輸(傳輸層協(xié)議規(guī)定,接收端必須發(fā)回確認脖岛,并且假如分組丟失朵栖,必須重新發(fā)送)
3)網(wǎng)絡(luò)層:負責(zé)相鄰計算機之間的通信
功能:
一、處理來自傳輸層的分組發(fā)送請求:收到請求后柴梆,將分組裝入IP數(shù)據(jù)報陨溅,填充報頭,選擇去往信宿機的路徑绍在,然后將數(shù)據(jù)報發(fā)往適當?shù)木W(wǎng)絡(luò)接口门扇。
二、處理輸入數(shù)據(jù)報:首先檢查其合法性偿渡,然后進行尋徑臼寄。假如該數(shù)據(jù)報已到達信宿機,則去掉報頭卸察,將剩下部分交給適當?shù)膫鬏攨f(xié)議脯厨;假如該數(shù)據(jù)報尚未到達信宿,則轉(zhuǎn)發(fā)該數(shù)據(jù)報坑质。
三合武、處理路徑、流控涡扼、擁塞等問題稼跳。
4)網(wǎng)絡(luò)接口層
這是TCP/IP軟件的最低層,負責(zé)接收IP數(shù)據(jù)報并通過網(wǎng)絡(luò)發(fā)送之吃沪,或者從網(wǎng)絡(luò)上接收物理幀汤善,抽出IP數(shù)據(jù)報,交給IP層票彪。IP红淡、IP地址 和 IP路由器
1)IP用于計算機之間的通信;
2)IP是無連接的通信協(xié)議降铸;
3)通過IP在旱,消息(或其它數(shù)據(jù))被分割成小的獨立的包,并通過Internet在計算機之間傳送推掸;
4)每臺計算機必須有一個IP地址桶蝎,才能夠連入Internet驻仅,作為網(wǎng)絡(luò)中的一個節(jié)點;
5)注意登渣,IP地址是 網(wǎng)絡(luò)號+主機號 的組合噪服;
6)當一個 IP 包從一臺計算機被發(fā)送,它會到達一個 IP 路由器胜茧;
IPI路由器負責(zé)將這個包(直接地或通過其它路由器)路由至它的目的地粘优;
在一個相同的通信中,一個IP包所經(jīng)由的路徑可能會和其他的包不同竹揍,而路由器負責(zé)根據(jù)通信量敬飒、網(wǎng)絡(luò)中的錯誤或者其它參數(shù),來進行正確地尋址芬位。TCP
1)TCP用于應(yīng)用程序間的通信无拗;
2)當應(yīng)用程序希望通過TCP與另一應(yīng)用程序通信時,它會發(fā)送一個通信請求(這個請求必須被送到一個確切的地址)昧碉。
在雙方“握手”之后英染,TCP 將在兩個應(yīng)用程序之間建立一個全雙工 (full-duplex) 的通信。域名
1)12位的阿拉伯數(shù)字被饿;
2)使用名字作為域名四康,比如 www.jd.com 。
3)DNS服務(wù)器負責(zé)將 域名 翻譯成 TCP/IP地址狭握,同時負責(zé)使用新的域名信息更新彼此的系統(tǒng)闪金。TCP/IP
1)TCP/IP 意味著 TCP 和 IP 在一起協(xié)同工作。
2)TCP 負責(zé)應(yīng)用軟件(比如你的瀏覽器)和網(wǎng)絡(luò)軟件之間的通信论颅;
IP 負責(zé)計算機之間的通信哎垦。
3)TCP 負責(zé)將數(shù)據(jù)分割并裝入 IP 包,然后在它們到達的時候重新組合它們恃疯;
IP 負責(zé)將包發(fā)送至接受者漏设。TCP三次握手
1)6位標志域
URG:緊急標志(“1”表明該位有效)
ACK:確認標志
PSH:推標志(該標志置位時,接收端不將該數(shù)據(jù)進行隊列處理今妄,而是盡可能快地將數(shù)據(jù)轉(zhuǎn)由應(yīng)用處理)
RST:復(fù)位標志(用于復(fù)位相應(yīng)的TCP連接)
SYN:同步標志(該標志僅在三次握手建立TCP連接時有效)
FIN:結(jié)束標志
2)所謂三次握手(Three-Way Handshake)即建立TCP連接
[image:1F08A71C-0279-47D9-8DE2-0AB00132ECE9-33499-0000F4FF95386F88/2964446-aa923712d5218eeb.png]
建立一個TCP連接時郑口,需要 Client 和 Server 總共發(fā)送 3 個包以確認連接的建立(在 socket 編程中,這一過程有客戶端執(zhí)行 connect 來觸發(fā))盾鳞。
- 第一次握手:Client 將標志位 SYN 置為 1犬性,并隨機產(chǎn)生一個值 seq = J,然后發(fā)送該數(shù)據(jù)包給 Server腾仅。此時仔夺,Client 進入 SYN_SENT 狀態(tài),等待 Server 確認攒砖。
- 第二次握手:Server 收到數(shù)據(jù)包后缸兔,由標志位 SYN=1 知道 Client 請求建立連接。于是吹艇,Server 將標志位 SYN 和 ACK 都置為 1惰蜜,ack = J+1,并隨機產(chǎn)生一個值 seq = K受神,然后發(fā)送數(shù)據(jù)包給 Client 以確認連接請求抛猖。此時,Server 進入 SYN_RCVD 狀態(tài)鼻听。
- 第三次握手:Client 收到確認后财著,檢查 ack 是否等于 J+1,ACK是否等于 1撑碴。如果都正確撑教,就將標志位 ACK 置為 1,ack = K+1醉拓,然后將數(shù)據(jù)包發(fā)送給 Server伟姐。 Server 端檢查 ack 是否等于 K+1,ACK 是否等于 1亿卤。如果都正確愤兵,則連接建立成功。
此時排吴,Client 和 Server 都進入 ESTABLISHED 狀態(tài)秆乳,完成第三次握手。
隨后钻哩,Client 和 Server 之間就可以開始傳輸數(shù)據(jù)了屹堰。
SYN攻擊:
在三次握手過程中,Server發(fā)送SYN-ACK之后憋槐,收到Client的ACK之前的TCP連接稱為半連接(half-open connect)双藕。此時,Server處于SYN_RCVD狀態(tài)阳仔,當收到ACK后忧陪,Server轉(zhuǎn)入ESTABLISHED狀態(tài)。
SYN攻擊就是Client在短時間內(nèi)偽造大量不存在的IP地址近范,并向Server不斷地發(fā)送SYN包嘶摊,Server回復(fù)確認包,并等待Client的確認评矩。由于源地址是不存在的叶堆,因此Server需要不斷重發(fā)直至超時,這些偽造的SYN包將產(chǎn)時間占用未連接隊列斥杜,導(dǎo)致正常的SYN請求因為隊列滿而被丟棄虱颗,從而引起網(wǎng)絡(luò)堵塞甚至系統(tǒng)癱瘓沥匈。
SYN攻擊時一種典型的DDOS攻擊。檢測SYN攻擊的方式:即當Server上有大量半連接狀態(tài)且源IP地址是隨機的忘渔,則可以斷定遭到SYN攻擊了高帖。
檢測SYN攻擊的終端指令:
#netstat -nap | grep SYN_RECV
- TCP四次揮手
1)所謂四次揮手(Four-Way Wavehand)即終止TCP連接
[image:7DB66895-82F6-4ECE-A250-C3FE0003FC10-33499-0000F6628BAFE971/2964446-2b9562b3a8b72fb2.png]
斷開一個TCP連接時,需要 Client 和 Server 總共發(fā)送 4 個包以確認連接的斷開(在socket編程中畦粮,這一過程由客戶端或服務(wù)端任一方執(zhí)行close來觸發(fā))散址。
::由于TCP連接是雙全工的,因此每個方向都必須要單獨進行關(guān)閉宣赔。::
1)第一次揮手:Client 發(fā)送一個 FIN预麸,用來關(guān)閉 Client 到 Server 的數(shù)據(jù)傳送。此時 Client 進入 FIN_WAIT_1 狀態(tài)儒将。
2)第二次揮手:Server 收到FIN后吏祸,發(fā)送一個ACK給 Client,確認序號為收到序號+1(與SYN相同椅棺,一個FIN占用一個序號)犁罩,此時Server 進入 CLOSE_WAIT狀態(tài)。
3)第三次揮手:Server發(fā)送一個FIN两疚,用來關(guān)閉Server到Client的數(shù)據(jù)傳送床估,Server進入LAST_ACK狀態(tài)。
4)第四次揮手:Client收到FIN后诱渤,Client進入TIME_WAIT狀態(tài)丐巫,接著發(fā)送一個ACK給Server,確認序號為收到序號+1勺美,Server進入CLOSED狀態(tài)递胧,完成四次揮手。