day26-Java網(wǎng)絡(luò)編程

26.02_網(wǎng)絡(luò)編程三要素之IP概述(掌握)

  • 每個(gè)設(shè)備在網(wǎng)絡(luò)中的唯一標(biāo)識(shí)
  • 每臺(tái)網(wǎng)絡(luò)終端在網(wǎng)絡(luò)中都有一個(gè)獨(dú)立的地址,我們?cè)诰W(wǎng)絡(luò)中傳輸數(shù)據(jù)就是使用這個(gè)地址献丑。
  • ipconfig:查看本機(jī)IP192.168.12.42
  • ping:測試連接192.168.40.62
  • 本地回路地址:127.0.0.1 , 255.255.255.255是廣播地址
  • IPv4:4個(gè)字節(jié)組成,4個(gè)0-255侠姑。大概42億创橄,30億都在北美,亞洲4億莽红。2011年初已經(jīng)用盡妥畏。
  • IPv6:8組邦邦,每組4個(gè)16進(jìn)制數(shù)。
  • 1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f
  • 1a2b::aaaa:0000:0000:0000:aabb:1f2f //兩個(gè)::代表省略了中間的0
  • 1a2b:0000:aaaa::aabb:1f2f

26.03_網(wǎng)絡(luò)編程三要素之端口號(hào)概述(掌握)

  • 每個(gè)程序在設(shè)備上的唯一標(biāo)識(shí)
  • 每個(gè)網(wǎng)絡(luò)程序都需要綁定一個(gè)端口號(hào)醉蚁,傳輸數(shù)據(jù)的時(shí)候除了確定發(fā)到哪臺(tái)機(jī)器上燃辖,還要明確發(fā)到哪個(gè)程序。
  • 端口號(hào)范圍從0-65535
  • 編寫網(wǎng)絡(luò)應(yīng)用就需要綁定一個(gè)端口號(hào)网棍,盡量使用1024以上的郭赐,1024以下的基本上都被系統(tǒng)程序占用了。
mysql: 3306
oracle: 1521
web: 80
tomcat: 8080
QQ: 4000
feiQ: 2425

26.04_網(wǎng)絡(luò)編程三要素協(xié)議(掌握)

  • 為計(jì)算機(jī)網(wǎng)絡(luò)中進(jìn)行數(shù)據(jù)交換而建立的規(guī)則确沸、標(biāo)準(zhǔn)或約定的集合捌锭。
  • UDP (類似發(fā)短信,對(duì)方可以不開機(jī)罗捎,甚至是假號(hào)碼)
    • 面向無連接观谦,數(shù)據(jù)不安全,速度快桨菜。不區(qū)分客戶端與服務(wù)端豁状。
  • TCP (類似打電話,撥通才能打通話倒得,http的底層就是TCP)
      * 面向連接(三次握手)泻红,數(shù)據(jù)安全,速度略低霞掺。分為客戶端和服務(wù)端谊路。
    • 三次握手: 1客戶端先向服務(wù)端發(fā)起請(qǐng)求, 2服務(wù)端響應(yīng)請(qǐng)求, 3傳輸數(shù)據(jù)

26.05_Socket通信原理圖解(了解)

  • 網(wǎng)絡(luò)上具有唯一標(biāo)識(shí)的IP地址和端口號(hào)組合在一起才能構(gòu)成唯一能識(shí)別的標(biāo)識(shí)符套接字。
  • 通信的兩端都有Socket菩彬。
  • 網(wǎng)絡(luò)通信其實(shí)就是Socket間的通信缠劝。
  • 數(shù)據(jù)在兩個(gè)Socket間通過IO流傳輸。
  • Socket在應(yīng)用程序中創(chuàng)建骗灶,通過一種綁定機(jī)制與驅(qū)動(dòng)程序建立關(guān)系惨恭,告訴自己所對(duì)應(yīng)的IP和port。

26.06_網(wǎng)絡(luò)編程(UDP傳輸)(了解)

  • 1.發(fā)送Send
byte[] d = "你好啊!".getBytes();
InetAddress ip = InetAddress.getByName("127.0.0.1");

DatagramSocket socket = new DatagramSocket(); //創(chuàng)建socket耙旦,相當(dāng)于是碼頭脱羡,隨機(jī)端口號(hào)
// 四個(gè)參數(shù)是: 數(shù)據(jù)、數(shù)據(jù)長度免都、地址锉罐、端口號(hào) 
DatagramPacket data = new DatagramPacket(d, d.length, ip, 3001);
socket.send(data);
  • 2.接收Receive
DatagramSocket socket = new DatagramSocket(3001); //指定端口號(hào),創(chuàng)建socket,相當(dāng)于創(chuàng)建碼頭
DatagramPacket data = new DatagramPacket(new byte[1024], 1024); //相當(dāng)于創(chuàng)建集裝箱
socket.receive(data);
socket.close();

byte[] arr = data.getData();  //獲取數(shù)據(jù)
int len = data.getLength();  //獲取有效的字節(jié)個(gè)數(shù)
System.out.println(new String(arr, 0,len));
  • 3.接收方獲取ip和端口號(hào)
String ip = packet.getAddress().getHostAddress();
int port = packet.getPort();

26.07_網(wǎng)絡(luò)編程(UDP傳輸優(yōu)化)

  • 接收端Receive
DatagramSocket socket = new DatagramSocket(3001); //指定端口號(hào),創(chuàng)建socket琴昆,相當(dāng)于創(chuàng)建碼頭
DatagramPacket data = new DatagramPacket(new byte[1024], 1024); //相當(dāng)于創(chuàng)建集裝箱
while(true) {
    socket.receive(data);
    byte[] arr = data.getData();  //獲取數(shù)據(jù)
    int len = data.getLength();  //獲取有效的字節(jié)個(gè)數(shù)
    System.out.println("收到內(nèi)容: " + new String(arr, 0,len));
    System.out.println("對(duì)方地址: " + data.getAddress().getHostAddress());
    System.out.println("端口: " + data.getPort() + "\r\n");
}
  • 發(fā)送端Send
Scanner sc = new Scanner(System.in);
System.out.println("請(qǐng)輸入發(fā)送的內(nèi)容:");
DatagramSocket socket = new DatagramSocket(); //創(chuàng)建socket氓鄙,相當(dāng)于是碼頭
InetAddress ip = InetAddress.getByName("127.0.0.1");
while(true) {
    String line = sc.nextLine();
    if ("q".equals(line)) break;
    byte[] d = line.getBytes();  //數(shù)據(jù)
    // 四個(gè)參數(shù)是: 數(shù)據(jù)、數(shù)據(jù)長度业舍、地址抖拦、端口號(hào) 
    DatagramPacket data = new DatagramPacket(d, d.length, ip, 3001);
    socket.send(data);   //發(fā)貨
}
socket.close(); //底層是IO流升酣,所以應(yīng)該也關(guān)掉
sc.close();

也可以開啟兩個(gè)線程,一個(gè)線程發(fā)送信息态罪,一個(gè)線程接收消息噩茄。

26.xx_GUI小程序遇到的懵逼知識(shí)點(diǎn)

這中間有一個(gè)GUI的聊天小程序,但是代碼很多复颈,就不粘貼了绩聘,畢竟Java桌面編程不是重點(diǎn),目標(biāo)是JavaEE耗啦,這里就將里面遇到的疑問點(diǎn)整理一下凿菩。

1.快捷鍵 Alt + Shift + L 把選中的變成局部變量
  Alt + Shift + z 選中代碼,按此快捷鍵 快速try
  Ctrl+Shift+Numpad_Divede(小鍵盤的/號(hào))  折疊全部方法
  Ctrl+Shift+Numpad_Multiply(小鍵盤的*號(hào))  展開全部方法

2.匿名內(nèi)部類里可以直接調(diào)用外部類的方法帜讲。
// 如下例子衅谷,寫全的方式為: ClassName.this.method();   ClassName為外部類的名字
new Runnable() {
    public void run(){
        method();
    }   
};

2.1 如果外部變量是外部類的本地變量(如在方法中定義的變量),
    必須聲明成final才能在內(nèi)部類中使用似将,正常是不可以修改這個(gè)變量的获黔,
    但如果變量搜索是對(duì)象,可以修改對(duì)象內(nèi)的屬性
2.2 如果外部變量是外部類的成員變量或類變量在验,內(nèi)部類可以直接修改

3. 最常見的基本類型數(shù)組寫法: int[] a = {1,2,3};     byte[] b = {1,2,3};
    這種寫法的全寫法是: int[] a = new int[]{1,2,3};   byte[] b = new byte[]{1,2,3}
所以見到  String str = new String(new byte[]{1,2,3});   不應(yīng)該懵逼玷氏,這僅僅是標(biāo)準(zhǔn)寫法

26.15_生成jar文件

Eclipse下,生成jar文件順序是:

1.項(xiàng)目或類上右鍵 --> Export --> Java下的JAR file
2.選擇好要導(dǎo)出jar的類和導(dǎo)出位置腋舌,點(diǎn)擊Next>
3.再次點(diǎn)擊Next>
4.選擇Main Class之后盏触,點(diǎn)擊Finish
圖一.png
圖二.png

26.16_網(wǎng)絡(luò)編程(TCP協(xié)議)(掌握)

  • 1.客戶端
    • 創(chuàng)建Socket連接服務(wù)端(指定ip地址,端口號(hào))通過ip地址找對(duì)應(yīng)的服務(wù)器
    • 調(diào)用SocketgetInputStream()getOutputStream()方法獲取和服務(wù)端相連的IO流
    • 輸入流可以讀取服務(wù)端輸出流寫出的數(shù)據(jù)
    • 輸出流可以寫出數(shù)據(jù)到服務(wù)端的輸入流
  • 2.服務(wù)端
    • 創(chuàng)建ServerSocket(需要指定端口號(hào))
    • 調(diào)用ServerSocket的accept()方法接收一個(gè)客戶端請(qǐng)求,得到一個(gè)Socket
    • 調(diào)用SocketgetInputStream()getOutputStream()方法獲取和客戶端相連的IO流
    • 輸入流可以讀取客戶端輸出流寫出的數(shù)據(jù)
    • 輸出流可以寫出數(shù)據(jù)到客戶端的輸入流

26.17_網(wǎng)絡(luò)編程(TCP協(xié)議代碼優(yōu)化)

  • 客戶端
Socket socket = new Socket("127.0.0.1", 3001); //指定ip和端口號(hào)
// 將InputStream 包裝成 BufferedReader 便于直接讀取一行數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 將OutputStream 包裝成  PrintStream 好處是能直接寫出換行和字符串
PrintStream ps = new PrintStream(socket.getOutputStream());

System.out.println(br.readLine());  //讀取服務(wù)器的回話
ps.println("我是客戶端侦厚,我就是想打個(gè)招呼而已耻陕。。"); //向服務(wù)器回話
socket.close();
  • 服務(wù)端
ServerSocket sever = new ServerSocket(3001);  //指定端口號(hào)
Socket socket = sever.accept();  //接收客戶端的請(qǐng)求

// 將InputStream 包裝成 BufferedReader 便于直接讀取一行數(shù)據(jù)
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// 將OutputStream 包裝成  PrintStream 好處是能直接寫出換行和字符串
PrintStream ps = new PrintStream(socket.getOutputStream());

ps.println("你好刨沦,我是服務(wù)器,有什么事膘怕?"); 
System.out.println(br.readLine());  //讀取客戶端的回復(fù)

26.18_網(wǎng)絡(luò)編程(服務(wù)端是多線程的)(掌握)

ServerSocket sever = new ServerSocket(3001);  //指定端口號(hào)
while(true) {
    final Socket socket = sever.accept();  //接收客戶端的請(qǐng)求
    new Thread(){
        public void run() {
            try {
                // 將InputStream 包裝成 BufferedReader 便于直接讀取一行數(shù)據(jù)
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                // 將OutputStream 包裝成  PrintStream 好處是能直接寫出換行和字符串
                PrintStream ps = new PrintStream(socket.getOutputStream());
                
                ps.println("你好想诅,我是服務(wù)器,有什么事岛心?"); 
                System.out.println(br.readLine());  //讀取客戶端的回復(fù)
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }.start();
}

26.19_網(wǎng)絡(luò)編程(練習(xí))

  • 客戶端向服務(wù)器寫字符串(鍵盤錄入),服務(wù)器(多線程)將字符串反轉(zhuǎn)后寫回,客戶端再次讀取到是反轉(zhuǎn)后的字符串
//反轉(zhuǎn)字符串
private String reverString(String str) {
    return new StringBuffer(str).reverse().toString();
}

26.20_網(wǎng)絡(luò)編程(客戶端向服務(wù)器上傳文件練習(xí))

  • 客戶端部分代碼
Socket socket = new Socket("192.168.3.109",3002);
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintStream ps = new PrintStream(socket.getOutputStream());

ps.println(file.getName());  // 發(fā)送文件名到服務(wù)端
String result = br.readLine(); //讀取服務(wù)器返回結(jié)果
if ("存在".equals(result)) {
    System.out.println("您上傳的文件已經(jīng)存在来破,請(qǐng)不要重復(fù)上傳..");
    socket.close();
    return;
}
System.out.println("文件不存在,開始上傳...");
FileInputStream fis = new FileInputStream(file);  //開始讀取文件到服務(wù)器
byte[] data = new byte[10 * 1024];
int len ;
while( (len = fis.read(data)) != -1) {
    ps.write(data, 0, len);
}

fis.close();
socket.close();
  • 服務(wù)端部分代碼
ServerSocket server = new ServerSocket(3002);
System.out.println("服務(wù)器啟動(dòng)忘古,端口號(hào) 3002 ");
while(true) {
    final Socket socket = server.accept();
    System.out.println("收到" + socket.getInetAddress().getHostAddress()+ "的請(qǐng)求送朱,開始處理...");
    new Thread(){
        public void run() {
            try {
                InputStream is = socket.getInputStream();
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                PrintStream ps = new PrintStream(socket.getOutputStream());
                
                String fileName = br.readLine();
                File dir = new File("/Users/houwan/Java");
                if (!dir.exists())  dir.mkdir();  //不存在就創(chuàng)建文件夾
                File file = new File(dir, fileName); //封裝成File對(duì)象
                if (file.exists()) {
                    ps.println("存在");
                    socket.close();  //關(guān)閉此次服務(wù)
                    return;
                }else ps.println("不存在");
                
                System.out.println("客戶端開始上傳文件...");
                FileOutputStream fos = new FileOutputStream(file);  //讀取客戶端上傳的文件娘荡,保持到本地
                byte[] data = new byte[10 * 1024];
                int len ;
                while ( (len = is.read(data)) != -1) {
                    fos.write(data, 0, len);
                }
                fos.close();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        };
    }.start();
}

END驶沼。
我是小侯爺大年。
在魔都艱苦奮斗,白天是上班族,晚上是知識(shí)服務(wù)工作者失都。
如果讀完覺得有收獲的話,記得關(guān)注和點(diǎn)贊哦庞溜。
非要打賞的話延刘,我也是不會(huì)拒絕的驾荣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末歧匈,一起剝皮案震驚了整個(gè)濱河市勘究,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖伏伯,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弄唧,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門患整,熙熙樓的掌柜王于貴愁眉苦臉地迎上來侮腹,“玉大人望抽,你說我怎么就攤上這事毁腿〖危” “怎么了?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵已烤,是天一觀的道長胯究。 經(jīng)常有香客問我臣嚣,道長,這世上最難降的妖魔是什么逻翁? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任八回,我火速辦了婚禮酷愧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘管引。我一直安慰自己士败,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谅将,像睡著了一般漾狼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饥臂,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天逊躁,我揣著相機(jī)與錄音,去河邊找鬼隅熙。 笑死稽煤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的猛们。 我是一名探鬼主播念脯,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼弯淘!你這毒婦竟也來了绿店?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤庐橙,失蹤者是張志新(化名)和其女友劉穎假勿,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體态鳖,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡转培,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浆竭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浸须。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖邦泄,靈堂內(nèi)的尸體忽然破棺而出删窒,到底是詐尸還是另有隱情,我是刑警寧澤顺囊,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布肌索,位于F島的核電站,受9級(jí)特大地震影響特碳,放射性物質(zhì)發(fā)生泄漏诚亚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一午乓、第九天 我趴在偏房一處隱蔽的房頂上張望站宗。 院中可真熱鬧,春花似錦益愈、人聲如沸份乒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽或辖。三九已至,卻和暖如春枣接,著一層夾襖步出監(jiān)牢的瞬間颂暇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工但惶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耳鸯,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓膀曾,卻偏偏與公主長得像县爬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子添谊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容