前言:
接著《java基礎(chǔ)知識01》,再來聊聊剩下的那些知識點(diǎn)。
歡迎大家關(guān)注我的公眾號 javawebkf,目前正在慢慢地將簡書文章搬到公眾號,以后簡書和公眾號文章將同步更新,且簡書上的付費(fèi)文章在公眾號上將免費(fèi)。
一、java基礎(chǔ)類庫:
1、String字符串:
字符串一旦被初始化,就不可以被改變,存放在方法區(qū)中的常量池中。用length()方法獲取長度。
2、StringBuffer字符串緩沖區(qū):
特點(diǎn):
- 可以對字符串內(nèi)容進(jìn)行修改。
- 是一個(gè)容器。
- 是可變長度的。
- 緩沖區(qū)中可以存儲任意類型的數(shù)據(jù)。
- 最終需要變成字符串。
容器通常具備一些固定的方法:append()、insert()、delete()、replace()等。
3、StringBuilder字符串緩沖區(qū):
JDK1.5出現(xiàn)StringBuiler;與StringBuffer區(qū)別如下:
- StringBuffer線程安全,StringBuilder線程不安全。
- 單線程操作,使用StringBuilder 效率高。多線程操作,使用StringBuffer 安全。
4、包裝類:
注意int ---> Integer 和 char ---> Character,這兩個(gè)基本類型對應(yīng)的包裝類不是首字母大寫就可以,其他的對應(yīng)的包裝類都是首字母大寫,注意區(qū)分。
5、Collections:
操作集合的工具類,提供了大量的操作集合的方法,十分方便,且方法都是靜態(tài)方法。
6、Arrays:
操作數(shù)組的工具類,提供了大量的操作數(shù)組的方法,里面的也都是靜態(tài)方法??聪旅孢@個(gè)常用方法:
asList方法:將數(shù)組轉(zhuǎn)換成list集合。
String[] arr = {"abc","kk","qq"};
List<String> list = Arrays.asList(arr);// 將arr數(shù)組轉(zhuǎn)成list集合。
二、集合:
1、集合和數(shù)組的區(qū)別:
- 數(shù)組是固定長度的;集合可變長度的。
- 數(shù)組可以存儲基本數(shù)據(jù)類型,也可以存儲引用數(shù)據(jù)類型;集合只能存儲引用數(shù)據(jù)類型。
- 數(shù)組存儲的元素必須是同一個(gè)數(shù)據(jù)類型;集合存儲的對象可以是不同數(shù)據(jù)類型。

2、Set集合:
無序(存入和取出順序有可能不一致),不可以存儲重復(fù)元素,必須保證元素唯一性。它的各個(gè)實(shí)現(xiàn)的特點(diǎn)如下:
- HashSet:底層數(shù)據(jù)結(jié)構(gòu)是哈希表,線程是不同步的。無序,高效;HashSet集合通過元素的hashCode方法和equals方法保證元素的唯一性。當(dāng)元素的hashCode值相同時(shí),才繼續(xù)判斷元素的equals是否為true。如果為true,那么視為相同元素,不存。如果為false,那么存儲。如果hashCode值不同,那么不判斷equals,從而提高對象比較的速度。
- LinkedHashSet:有序,hashset的子類。
- TreeSet:對Set集合中的元素的進(jìn)行指定順序的排序,排序需要依據(jù)元素自身具備的比較性,如果元素不具備比較性,在運(yùn)行時(shí)會發(fā)生ClassCastException異常。線程不同步。TreeSet底層的數(shù)據(jù)結(jié)構(gòu)就是二叉樹。
3、List集合:
有序(元素存入集合的順序和取出的順序一致),元素都有索引。元素可以重復(fù)。它的實(shí)現(xiàn)有三個(gè):
- ArrayList:底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組,線程不同步,ArrayList替代了Vector,查詢元素的速度非??臁?/li>
- LinkedList:底層的數(shù)據(jù)結(jié)構(gòu)是鏈表,線程不同步,增刪元素的速度非???。
- Vector:底層的數(shù)據(jù)結(jié)構(gòu)就是數(shù)組,線程同步的,Vector無論查詢和增刪都巨慢。
4、Map集合:
以鍵值對形式存儲元素,其各個(gè)實(shí)現(xiàn)的特點(diǎn)如下:
- Hashtable:底層是哈希表數(shù)據(jù)結(jié)構(gòu),是線程同步的。不可以存儲null鍵,null值。
- HashMap:底層是哈希表數(shù)據(jù)結(jié)構(gòu),是線程不同步的。可以存儲null鍵,null值。替代了Hashtable。
- TreeMap:底層是二叉樹結(jié)構(gòu),可以對map集合中的鍵進(jìn)行指定順序的排序。
5、集合使用技巧:
- 看到Array就是數(shù)組結(jié)構(gòu),有角標(biāo),查詢速度很快。
- 看到link就是鏈表結(jié)構(gòu):增刪速度快,而且有特有方法:addFirst()、 addLast()、 removeFirst()、 removeLast()、 getFirst()、getLast();
- 看到hash就是哈希表,就要想到哈希值,就要想到唯一性,就要想到存入到該結(jié)構(gòu)的中的元素必須覆蓋hashCode和equals方法。
- 看到tree就是二叉樹,就要想到排序,就要用到比較。
- 如何判斷使用哪個(gè)集合?存儲一個(gè)元素且要保證唯一性就用Set,存儲一個(gè)元素不用保證唯一性就用List,存儲含有映射關(guān)系的對象就用Map。
三、IO流:
IO流就是用來處理設(shè)備上的數(shù)據(jù)的,輸入和輸出是以內(nèi)存為參照物。InputStream,輸入流,把計(jì)算機(jī)的數(shù)據(jù)輸入到內(nèi)存,所以是讀;OutputStream,輸出流,把內(nèi)存中的數(shù)據(jù)輸出到計(jì)算機(jī),所以是寫。
1、IO流分類:
- 字節(jié)流(InputStream 和 OutputStream):處理字節(jié)數(shù)據(jù)的流對象。設(shè)備上的數(shù)據(jù)無論是圖片、視頻還是文字,它們都以二進(jìn)制存儲的。計(jì)算機(jī)中的最小數(shù)據(jù)單元就是字節(jié),這就意味著,字節(jié)流可以處理設(shè)備上的所有數(shù)據(jù),所以字節(jié)流一樣可以處理字符數(shù)據(jù)。
- 字符流(Reader 和 Writer):因?yàn)槊總€(gè)國家的字符都不一樣,所以涉及到了字符編碼問題。GBK編碼的中文用unicode編碼解析是有問題的,所以需要獲取中文字節(jié)數(shù)據(jù)的同時(shí)再指定的編碼表才可以解析正確數(shù)據(jù)。為了方便于文字的解析,所以將字節(jié)流和編碼表封裝成對象,這個(gè)對象就是字符流。只要操作字符數(shù)據(jù),優(yōu)先考慮使用字符流體系。
2、IO流繼承體系:
(1).字節(jié)流:
InputStream:是表示字節(jié)輸入流的所有類的超類。
- |--- FileInputStream:從文件系統(tǒng)中的某個(gè)文件中獲得輸入字節(jié)。哪些文件可用取決于主機(jī)環(huán)境。FileInputStream 用于讀取諸如圖像數(shù)據(jù)之類的原始字節(jié)流。要讀取字符,請考慮使用 FileReader。
- |--- FilterInputStream:包含其他一些輸入流,它將這些流用作其基本數(shù)據(jù)源,它可以直接傳輸數(shù)據(jù)或提供一些額外的功能。
????? |--- BufferedInputStream:該類實(shí)現(xiàn)緩沖的輸入流。
????? |--- Stream - |--- ObjectInputStream:
- |--- PipedInputStream:
OutputStream:此抽象類是表示輸出字節(jié)流的所有類的超類。
- |--- FileOutputStream:文件輸出流是用于將數(shù)據(jù)寫入 File 或 FileDescriptor 的輸出流。
- |--- FilterOutputStream:此類是過濾輸出流的所有類的超類。
????? |--- BufferedOutputStream:該類實(shí)現(xiàn)緩沖的輸出流。
????? |--- PrintStream
????? |--- DataOutputStream - |--- ObjectOutputStream
- |--- PipedOutputStream
(2).字符流:
Reader:用于讀取字符流的抽象類。子類必須實(shí)現(xiàn)的方法只有 read(char[], int, int) 和 close()。
- |--- BufferedReader:從字符輸入流中讀取文本,緩沖各個(gè)字符,從而實(shí)現(xiàn)字符、數(shù)組和行的高效讀取。 可以指定緩沖區(qū)的大小,或者可使用默認(rèn)的大小。大多數(shù)情況下,默認(rèn)值就足夠大了。
????? |---LineNumberReader:跟蹤行號的緩沖字符輸入流。此類定義了 setLineNumber(int)方法 和 getLineNumber()方法,它們可分別用于設(shè)置和獲取當(dāng)前行號。 - |--- InputStreamReader:稱為轉(zhuǎn)換流,是字節(jié)流通向字符流的橋梁:它使用指定的charset讀取字節(jié)并將其解碼為字符。它使用的字符集可以由名稱指定或顯式給定,或者可以接受平臺默認(rèn)的字符集。
????? |--- FileReader:InputStreamReader的子類,最常用的轉(zhuǎn)換流。用來讀取字符文件的便捷類。 - |--- CharArrayReader
- |---StringReader
Writer:寫入字符流的抽象類。子類必須實(shí)現(xiàn)的方法僅有 write(char[], int, int)、flush() 和 close()。
- |--- BufferedWriter:將文本寫入字符輸出流,緩沖各個(gè)字符,從而提供單個(gè)字符、數(shù)組和字符串的高效寫入。
- |--- OutputStreamWriter:稱為轉(zhuǎn)換流,是字符流通向字節(jié)流的橋梁:可使用指定的charset將要寫入流中的字符編碼成字節(jié)。它使用的字符集可以由名稱指定或顯式給定,否則將接受平臺默認(rèn)的字符集。
????? |--- FileWriter:OutputStreamWriter的子類,最常用的轉(zhuǎn)換流。用來寫入字符文件的便捷類。 - |--- PrintWriter
- |--- CharArrayWriter
- |--- StringWriter
下面介紹幾個(gè)流的用法,看下面例子:
/*創(chuàng)建可以讀取文本文件的流對象,F(xiàn)ileReader讓創(chuàng)建好的流對象和指定的文件相關(guān)聯(lián)。*/
FileReader fr = new FileReader("demo.txt");
int ch = 0;
while((ch = fr.read())!= -1) { //條件是沒有讀到結(jié)尾
System.out.println((char)ch); //調(diào)用讀取流的read方法,讀取一個(gè)字符。
}
fr.close();
/* =======================下面這種自定義緩沖區(qū)的方式更高效=============================== */
FileReader fr = new FileReader("demo.txt"); //創(chuàng)建讀取流對象和指定文件關(guān)聯(lián)。
//因?yàn)橐褂胷ead(char[])方法,將讀取到字符存入數(shù)組。
//所以要?jiǎng)?chuàng)建一個(gè)字符數(shù)組,一般數(shù)組的長度都是1024的整數(shù)倍。
char[] buf = new char[1024];
int len = 0;
while(( len=fr.read(buf)) != -1) {
System.out.println(new String(buf,0,len));
}
fr.close();
/* ==================================== 高效寫數(shù)據(jù) ======================================*/
FileWriter fw = new FileWriter("bufdemo.txt");
BufferedWriter bufw = new BufferedWriter(fw);//讓緩沖區(qū)和指定流相關(guān)聯(lián)。
for(int x=0; x<4; x++){
bufw.write(x+"abc");
bufw.newLine(); //寫入一個(gè)換行符,這個(gè)換行符可以依據(jù)平臺的不同寫入不同的換行符。
bufw.flush();//對緩沖區(qū)進(jìn)行刷新,可以讓數(shù)據(jù)到目的地中。
}
bufw.close();//關(guān)閉緩沖區(qū),其實(shí)就是在關(guān)閉具體的流。
/* ==================================== 高效讀數(shù)據(jù) ======================================*/
FileReader fr = new FileReader("bufdemo.txt");
BufferedReader bufr = new BufferedReader(fr);
String line = null;
while((line=bufr.readLine())!=null){ //readLine方法返回的時(shí)候是不帶換行符的。
System.out.println(line);
}
bufr.close();
3、流的操作規(guī)律:
從上面的流體系可以看到,Java提供了很多的流供我們使用,感覺很復(fù)雜。那么使用的時(shí)候該如何選擇呢?就得明確以下幾點(diǎn):
(1). 明確目的:
- 讀數(shù)據(jù):使用InputStream、Reader體系
- 寫數(shù)據(jù):使用OutputStream、Writer體系
(2). 操作的數(shù)據(jù)是否是純文本數(shù)據(jù)?
- 如果是:讀數(shù)據(jù):Reader;寫數(shù)據(jù):Writer
- 若不是:讀數(shù)據(jù):InputStream;寫數(shù)據(jù):OutputStream
(3). 雖然確定了一個(gè)體系,但是該體系中有太多的對象,到底用哪個(gè)呢?
- 從何處讀取數(shù)據(jù):硬盤(File),內(nèi)存(流),鍵盤(System.in)
- 把數(shù)據(jù)寫到何處:硬盤(File),內(nèi)存(流),控制臺(System.out)
(4). 需要在基本操作上附加其他功能嗎?比如緩沖。如果需要就進(jìn)行裝飾,那就用帶Buffer的流。
(5). 凡是操作設(shè)備上的文本數(shù)據(jù),涉及編碼轉(zhuǎn)換,必須使用轉(zhuǎn)換流。
4、File類:
將文件系統(tǒng)中的文件和文件夾封裝成了對象。提供了更多的屬性和行為可以對這些文件和文件夾進(jìn)行操作。這些是流對象辦不到的,因?yàn)榱髦徊僮鲾?shù)據(jù)。常用方法如下:
(1). 創(chuàng)建:
boolean createNewFile(); //在指定目錄下創(chuàng)建文件,如果該文件已存在,則不創(chuàng)建。
boolean mkdir(); //創(chuàng)建此抽象路徑名指定的目錄。
boolean mkdirs(); //創(chuàng)建多級目錄。
(2). 刪除:
boolean delete(); //刪除此抽象路徑名表示的文件或目錄。
void deleteOnExit(); //在虛擬機(jī)退出時(shí)刪除。
// 注意:在刪除文件夾時(shí),必須保證這個(gè)文件夾中沒有任何內(nèi)容,才可以將該文件夾用delete刪除。
// java刪除文件不走回收站。要慎用。
(3). 獲取:
long length(); //獲取文件大小。
String getName(); //返回由此抽象路徑名表示的文件或目錄的名稱。
String getPath(); //將此抽象路徑名轉(zhuǎn)換為一個(gè)路徑名字符串。
String getAbsolutePath(); //返回此抽象路徑名的絕對路徑名字符串。
String getParent(); //返回此抽象路徑名父目錄的抽象路徑名,如果此路徑名沒有指定父目錄,則返回 null。
long lastModified(); //返回此抽象路徑名表示的文件最后一次被修改的時(shí)間。
File.pathSeparator; //返回當(dāng)前系統(tǒng)默認(rèn)的路徑分隔符,windows默認(rèn)為 “;”。
File.Separator; //返回當(dāng)前系統(tǒng)默認(rèn)的目錄分隔符,windows默認(rèn)為 “\”。
(4). 判斷:
boolean exists();// 判斷文件或者文件夾是否存在。
boolean isDirectory(); //測試此抽象路徑名表示的文件是否是一個(gè)目錄。
boolean isFile(); //測試此抽象路徑名表示的文件是否是一個(gè)標(biāo)準(zhǔn)文件。
boolean isHidden(); //測試此抽象路徑名指定的文件是否是一個(gè)隱藏文件。
boolean isAbsolute(); //測試此抽象路徑名是否為絕對路徑名。
(5). 重命名:
boolean renameTo(File dest); //可以實(shí)現(xiàn)移動(dòng)的效果。剪切+重命名。
(6). String[] list():列出指定目錄下的當(dāng)前的文件和文件夾的名稱。包含隱藏文件。
如果調(diào)用list方法的File 對象中封裝的是一個(gè)文件,那么list方法返回?cái)?shù)組為null。如果封裝的對象不存在也會返回null。只有封裝的對象存在并且是文件夾時(shí),這個(gè)方法才有效。
四、網(wǎng)絡(luò)編程:
所謂網(wǎng)絡(luò)編程,其實(shí)可以簡單的理解為就是在兩個(gè)或兩個(gè)以上的設(shè)備之間傳輸數(shù)據(jù)。
1、相關(guān)概念:
- IP:為了能夠識別接入互聯(lián)網(wǎng)的每個(gè)設(shè)備,網(wǎng)絡(luò)中的每個(gè)設(shè)備都會有一個(gè)唯一的數(shù)字標(biāo)識,這個(gè)標(biāo)識就是IP。就像手機(jī)號用來標(biāo)識不同的手機(jī)用戶一樣。每個(gè)計(jì)算機(jī)在聯(lián)網(wǎng)后都有一個(gè)唯一的合法IP地址。
- 域名:由于IP地址是一串?dāng)?shù)字不方便記憶,所以為了方便記憶就有了域名這個(gè)概念。就像手機(jī)號碼不方便記憶,你會設(shè)置備注一樣。一個(gè)IP地址可以對應(yīng)多個(gè)域名,一個(gè)域名只能對應(yīng)一個(gè)IP。
- DNS服務(wù)器:上面說了,IP是聯(lián)網(wǎng)計(jì)算機(jī)的唯一標(biāo)識,但是使用的時(shí)候我們又會用域名代替IP,所以在實(shí)際傳輸數(shù)據(jù)前需要將域名轉(zhuǎn)換為IP地址。實(shí)現(xiàn)將域名解析為IP地址的服務(wù)器就叫DNS服務(wù)器。所以我們在地址欄請求某個(gè)域名時(shí),首先請求的是DNS服務(wù)器。
- 端口:IP和域名就能很方便的在網(wǎng)絡(luò)中找到該IP對應(yīng)的計(jì)算機(jī),但是一個(gè)計(jì)算機(jī)可以同時(shí)運(yùn)行多個(gè)網(wǎng)絡(luò)程序,為了區(qū)分每個(gè)程序,就引入了端口這個(gè)概念。IP是區(qū)分不同的計(jì)算機(jī)的,端口就是區(qū)分同一臺電腦上不同的應(yīng)用程序的。有效端口:0 ~ 65535,其中0 ~1024系統(tǒng)使用或保留端口。
有了IP + 端口,就可以標(biāo)識唯一的一臺計(jì)算機(jī)上的一個(gè)唯一的程序了。但是網(wǎng)絡(luò)程序之間還需要進(jìn)行數(shù)據(jù)交換,所以還需要了解網(wǎng)絡(luò)通訊。
- 網(wǎng)絡(luò)通訊:可以理解為就是不同計(jì)算機(jī)之間進(jìn)行數(shù)據(jù)交換。網(wǎng)絡(luò)通訊基于“請求-響應(yīng)”模型。所謂的“請求-響應(yīng)”模型,就是一問一答都形式,一端請求,另一端就響應(yīng),不請求就不會有響應(yīng)。
- 客戶端(client):在網(wǎng)絡(luò)通訊中,主動(dòng)發(fā)起通訊的程序被稱作客戶端程序,簡稱客戶端。
- 服務(wù)器(server):而在一次網(wǎng)絡(luò)通訊中等待連接的程序叫做服務(wù)器端程序,簡稱服務(wù)器。
這樣的網(wǎng)絡(luò)編程結(jié)構(gòu)被稱作客戶端/服務(wù)器結(jié)構(gòu),簡稱C/S結(jié)構(gòu)。這種結(jié)構(gòu)的程序通用性差,一個(gè)程序的客戶端只能和與之對應(yīng)的服務(wù)器通訊,而不能和其他服務(wù)器通訊。我們還有另一種方式,就是使用瀏覽器作為通用客戶端與服務(wù)器進(jìn)行通訊,這種使用瀏覽器作為客戶端的結(jié)構(gòu)稱作瀏覽器/服務(wù)器結(jié)構(gòu),簡稱B/S結(jié)構(gòu)。
- 協(xié)議:這是網(wǎng)絡(luò)編程中最重要也是最復(fù)雜的一個(gè)概念。網(wǎng)絡(luò)編程就是運(yùn)行在不同計(jì)算機(jī)中的兩個(gè)程序之間的數(shù)據(jù)交互。但是計(jì)算機(jī)畢竟不是人腦,接收到的數(shù)據(jù)它也無法理解。為了讓計(jì)算機(jī)能理解接收的數(shù)據(jù),就需要規(guī)定該數(shù)據(jù)的格式,這個(gè)數(shù)據(jù)的格式就叫做協(xié)議。就比如發(fā)送電報(bào),先按照某種規(guī)則加密,另一端接收到的是加密后的電報(bào),想要知道電報(bào)內(nèi)容,就得按照規(guī)則解密,這種規(guī)則就叫協(xié)議。協(xié)議格式是隨便編寫的,只要按照這種格式能生成唯一的編碼,另一端能唯一的解析出數(shù)據(jù)的內(nèi)容即可。也正是這個(gè)原因,導(dǎo)致客戶端只能和與之對應(yīng)的服務(wù)器通訊。
- 網(wǎng)絡(luò)通訊方式:TCP和UDP方式。TCP方式建立專門的虛擬連接,進(jìn)行可靠的數(shù)據(jù)傳輸,所以重要的數(shù)據(jù)一般采用這種方式傳輸;而UDP方式不需要建立虛擬連接,數(shù)據(jù)傳輸不可靠。
2、 網(wǎng)絡(luò)編程步驟:
(1). 客戶端網(wǎng)絡(luò)編程步驟:
- 建立網(wǎng)絡(luò)連接
- 交換數(shù)據(jù)
- 關(guān)閉網(wǎng)絡(luò)連接
(2). 服務(wù)端網(wǎng)絡(luò)編程步驟:
- 監(jiān)聽端口
- 獲得連接
- 交換數(shù)據(jù)
- 關(guān)閉連接
3、Java網(wǎng)絡(luò)編程:
和網(wǎng)絡(luò)編程相關(guān)的API位于java.net包下。
(1). 部分相關(guān)API如下:
- InetAddress:java 中ip對象
- Socket:套接字,通信的端點(diǎn)。就是為網(wǎng)絡(luò)服務(wù)提供的一種機(jī)制,通信的兩端都有Socket,網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信,數(shù)據(jù)在兩個(gè)Socket間通過IO傳輸。
- DatagramPacket:通過這個(gè)對象中的方法,就可以獲取到數(shù)據(jù)包中的各種信息。
- DatagramSocket.:封裝了udp傳輸協(xié)議的socket對象。
(2). UDP方式案例:
客戶端:
public static void main(String[] args)throws Exception {
//1,建立udp的socket服務(wù)。
DatagramSocket ds = new DatagramSocket(8888);//指定發(fā)送端口,不指定系統(tǒng)會隨機(jī)分配。
//2,明確要發(fā)送的具體數(shù)據(jù)。
String text = "演示udp傳輸";
byte[] buf = text.getBytes();
//3,將數(shù)據(jù)封裝成了數(shù)據(jù)包。
DatagramPacket dp = new DatagramPacket(buf,
buf.length,InetAddress.getByName("10.1.31.127"),10000);
//4,用socket服務(wù)的send方法將數(shù)據(jù)包發(fā)送出去。
ds.send(dp);
//5,關(guān)閉資源。
ds.close();
}
服務(wù)端:
public static void main(String[] args) throws Exception{
//1,創(chuàng)建udp的socket服務(wù)。
DatagramSocket ds = new DatagramSocket(10000);
//2,定義數(shù)據(jù)包,用于存儲接收到數(shù)據(jù)。先定義字節(jié)數(shù)組,數(shù)據(jù)包會把數(shù)據(jù)存儲到字節(jié)數(shù)組中。
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
// 3,通過socket服務(wù)的接收方法將收到的數(shù)據(jù)存儲到數(shù)據(jù)包中。
ds.receive(dp);//該方法是阻塞式方法。
// 4,通過數(shù)據(jù)包的方法獲取數(shù)據(jù)包中的具體數(shù)據(jù)內(nèi)容,比如ip,端口,數(shù)據(jù)等等。
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(),0,dp.getLength());//將字節(jié)數(shù)組中的有效部分轉(zhuǎn)成字符串。
System.out.println(ip+":"+port+"--"+text);
// 5,關(guān)閉資源。
ds.close();
}
(3). TCP方式案例:
客戶端:
public static void main(String[] args) throws Exception{
Socket s = new Socket("10.1.31.69",10002);
OutputStream out = s.getOutputStream();//獲取了socket流中的輸出流對象。
out.write("tcp演示".getBytes());
s.close();
}
服務(wù)端:
public static void main(String[] args) throws Exception{
ServerSocket ss = new ServerSocket(10002);//建立服務(wù)端的socket服務(wù)
Socket s = ss.accept();//獲取客戶端對象
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip+".....connected");
//可以通過獲取到的socket對象中的socket流和具體的客戶端進(jìn)行通訊。
InputStream in = s.getInputStream();//讀取客戶端的數(shù)據(jù),使用客戶端對象的socket讀取流
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
//如果通訊結(jié)束,關(guān)閉資源。注意:要先關(guān)客戶端,在關(guān)服務(wù)端。
s.close();
ss.close();
}
總結(jié):
《java基礎(chǔ)知識01》和本文簡陋的總結(jié)了一些java基礎(chǔ)的知識點(diǎn),由于本人只是個(gè)小白,只能在此拋磚引玉,望各位大神多多指點(diǎn)!