1. 程式人生 > >java學習筆記之網絡編程

java學習筆記之網絡編程

col client 應用場景 err pri 多圖片 data oca 網絡

網絡編程

一.網絡通信協議

  1.網絡協議

    不同的操作系統,不同的硬件設備上都能夠聯網,是因為互聯網設計規定了一套標準,這套標準就被稱為網絡協議,網絡協議規定了網絡傳輸的格式,速率和方式;

  2.TCP/IP協議

    是一組協議:HTTP ,FTP,SMTP,DNS

    TCP:傳輸控制協議

    IP:互聯網協議

    TCP/IP協議的分層:

      應用層:上位機應用程序,比如說qq,用來產生數據和顯示數據

      傳輸層:端口號 加入一些標誌位,保證數據傳輸的準確性

      網絡層:ip地址 用來尋找對方電腦在哪裏

      鏈路層:網卡驅動 用來發送或接收數據

  3. IP地址:

    在一個網絡中ip地址可以唯一標識一臺電腦。

     ipv4:xxx.xxx.xxx.xxx 點分十進制 32個二進制位來描述ip:21個億

     ipv6:128個二進制位來描述ip:無數個

  4.端口號:

    就是聯網的每一個應用程序制定一個編號,編號可以唯一標識一個應用程序

    1-65535

    1-1024:系統使用

    1024-6000:系統保留

    >6000自己使用

    一臺電腦的應用程序想和另一臺電腦的一個程序通信 必須知道ip地址和端口號

二.UDP 和TCP協議

  1.udp協議:用戶數據報協議

    面向無連接的協議,兩臺電腦在通信之前不需要建立連接,發送端只管發送,不會關心接收端是否已經收到,或者接收端是否存在

    優點:數據傳輸速度快,效率高

    缺點:數據安全性不高,數據容易丟失;

    應用場景:電話會議,視頻直播,網絡會議---->實時性

  2.tcp協議:傳輸控制協議

    兩臺電腦在通信之前必須建立連接(三次握手),每次發送完數據,都會有一個反饋信息。

    優點:數據安全性高,可靠性強

    缺點:傳輸數度慢,效率低

    應用場景:密碼管理,金融支付,理財系統

三.InetAddress類

 1 /*
 2      * InetAddress類用來描述一臺電腦的信息:ip地址,計算機名和其他信息
 3      * public  static InetAddress getLocalHost();可以獲取本地電腦主機的信息
4 * public static InetAddress getByName(String host);可以獲取任意電腦主機的信息 5 */ 6 public static void main(String[] args)throws Exception { 7 //獲取本地電腦主機的信息 8 InetAddress address=InetAddress.getLocalHost(); 9 //使用getHostAddress()方法獲取本地的ip地址 10 String ip=address.getHostAddress(); 11 //使用getHostName()方法獲取本地主機名 12 String hostName=address.getHostName(); 13 //-------------------------getByName()方法的使用--------------------------------- 14 //獲取指定指定主機的電腦信息 15 InetAddress bdAddress=InetAddress.getByName("www.baidu.com");//這裏參數可以是網址,ip地址,和主機名 16 //獲取百度的ip地址 17 String baiDuIp=bdAddress.getHostAddress(); 18 System.out.println("百度的IP地址是:"+baiDuIp); 19 //獲取百度的主機名 20 String baiDuHostName=bdAddress.getHostName(); 21 System.out.println("百度的主機名是:"+baiDuHostName); 22 }

四.UDP編程

技術分享圖片

  1.使用udp實現發送端的編寫:

 1 public class SendDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:建立一個碼頭,該程序有一個對外連接的窗口
 5         /*
 6          * 套接字
 7          */
 8         DatagramSocket ds = new DatagramSocket();
 9         //2:準備要發送的貨物:數據
10         byte[] bytes = "hello udp!!!!".getBytes();
11         
12         //3:準備一個集裝箱,將貨物取裝入集裝箱
13         /*
14          * 參1:你要發送的數據
15          * 參2:你要發送的字節長度
16          * 參3: 表示接收端的ip地址
17          * 參4: 表示接收端的端口號
18          */
19         //"192.168.65.103" --->InetAddress
20         InetAddress address = InetAddress.getByName("192.168.65.255");
21         DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, 8888);
22         //4: 發送集裝箱
23         ds.send(dp);
24         //5:關流
25         ds.close();
26     }
27 
28 }

  2.使用udp協議實現接收端編寫:

 1 public class ReceiveDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:建立一個碼頭,並綁定端口
 5         DatagramSocket ds = new DatagramSocket(8888);
 6         //2:準備一個空的集裝箱,用來接收數據
 7         /*
 8          * 參1:表示要接收的數據存放在哪個字節數組
 9          * 參2:表示要接收的數據長度
10          */
11         byte[] bytes = new byte[1024]; //"hello" ip 和端口
12         DatagramPacket dp = new DatagramPacket(bytes, bytes.length);    
13         //3:接收數據
14         ds.receive(dp); //如果沒有接收到數據,則該方法阻塞    
15         //4:從集裝箱中獲取數據
16         byte[] data = dp.getData(); //"hello"
17         int length = dp.getLength();
18         //獲取發送端的ip
19         InetAddress address = dp.getAddress();
20         String ip = address.getHostAddress();
21         //5:打印接收到的數據
22         System.out.println(ip+":"+new String(data,0,length));
23     }
24 
25 }

五.TCP編程

  交互流程圖:

技術分享圖片

  圖片上傳案例:

     客戶端的編寫:

 1 public class ClientDemo {
 2     public static void main(String[] args) throws IOException {
 3         //1:獲取文件的輸入流(讀)
 4         FileInputStream fis = new FileInputStream("a.jpg");
 5         
 6 //        BufferedInputStream bufis = new BufferedInputStream(fis);
 7         
 8         //2:獲取套接字的輸出流
 9         InetAddress address = InetAddress.getLocalHost();
10         Socket socket = new Socket(address, 9999);
11         OutputStream os = socket.getOutputStream();
12 //        BufferedOutputStream bufos = new BufferedOutputStream(os);
13         
14         //3:將從文件輸入流讀取的數據寫到套接字的輸出流
15         byte[] bytes = new byte[1024];
16         int len = 0;
17         while((len = fis.read(bytes)) != -1){
18             os.write(bytes,0,len);
19         }
20         //關閉輸出流
21 //        socket.close();  //輸入流和輸出流都關閉
22         socket.shutdownOutput();  //值關閉輸出流
23         //--接收反饋信息 
24         //3.1獲取套接字的輸入流
25          InputStream is = socket.getInputStream();
26         //3.2 讀取數據
27          len = is.read(bytes);
28         System.out.println(new String(bytes,0,len));
29         //4:關流
30         socket.close();
31         fis.close();
32     }
33 
34 }

      服務器端的編寫:

 1 public class ServerDemo {
 2     public static void main(String[] args) throws IOException {
 3         //1:獲取套接字的輸入流
 4         ServerSocket sSocket = new ServerSocket(9999);
 5         Socket cSocket = sSocket.accept();
 6         InputStream is = cSocket.getInputStream();
 7         
 8         //2:獲取文件的輸出流
 9         FileOutputStream fos = new FileOutputStream("D:\\Server\\a.jpg");
10         /*
11          * while循環要想結束必須read方法讀取-1,在普通文件的讀取中,讀取到文件末尾就能-1
12          * 但是套接字沒有文件末尾,所以不能返回-1
13          * 
14          * 如何讓服務器讀取到-1?
15          *  只要讓客戶端把輸出流進行關閉
16          */
17         //3:將從套接字輸入流讀取的數據寫入文件的輸出流
18         byte[] bytes = new byte[1024];
19         int len = 0;
20         while((len = is.read(bytes)) != -1){
21             fos.write(bytes, 0, len);
22         }
23         //--在這裏給客戶端反饋
24         //3.1 獲取套接字的輸出流
25         OutputStream os = cSocket.getOutputStream();
26         //3.2 發送反饋信息
27         os.write("上傳成功啦!".getBytes());
28         //4:關流
29         fos.close();
30         cSocket.close();
31         sSocket.close();
32     }
33 }

  多圖片上傳案例:

  客戶端:

 1 public class ClientDemo {
 2 
 3     public static void main(String[] args) throws IOException {
 4         //1:獲取文件的輸入流(讀)
 5         FileInputStream fis = new FileInputStream("a.jpg");
 6         
 7 //        BufferedInputStream bufis = new BufferedInputStream(fis);
 8         
 9         //2:獲取套接字的輸出流
10         InetAddress address = InetAddress.getLocalHost();
11         Socket socket = new Socket(address, 10086);
12         OutputStream os = socket.getOutputStream();
13 //        BufferedOutputStream bufos = new BufferedOutputStream(os);
14         
15         //3:將從文件輸入流讀取的數據寫到套接字的輸出流
16         byte[] bytes = new byte[1024];
17         int len = 0;
18         while((len = fis.read(bytes)) != -1){
19             os.write(bytes,0,len);
20         }
21         //關閉輸出流
22 //        socket.close();  //輸入流和輸出流都關閉
23         socket.shutdownOutput();  //值關閉輸出流
24         //--接收反饋信息 
25         //3.1獲取套接字的輸入流
26          InputStream is = socket.getInputStream();
27         //3.2 讀取數據
28          len = is.read(bytes);
29         System.out.println(new String(bytes,0,len));
30         //4:關流
31         socket.close();
32         fis.close();
33     }
34 
35 }

  服務器端:

 1 public class ServerDemo {
 2     public static void main(String[] args) throws IOException {
 3         ServerSocket sSocket = new ServerSocket(10086);
 4         //有多少個請求,accept就執行多少次
 5         while(true){
 6             Socket cSocket = sSocket.accept();
 7             //每來一個請求,就創建一個線程,去處理請求
 8             Thread t = new Thread(new MyRunnable(cSocket));
 9             t.start();
10         }
11     }
12 }

  多線程:

 1 public class MyRunnable implements Runnable {
 2     private Socket cSocket;
 3     
 4     public MyRunnable(Socket cSocket) {
 5         this.cSocket = cSocket;
 6     }
 7 
 8     public MyRunnable() {
 9     }
10     //a.txt --->a(2).txt
11     @Override
12     public void run() {
13         try {
14             //1: 獲取套接字的輸入流
15             InputStream is = cSocket.getInputStream();
16             long time = System.currentTimeMillis();
17             
18             //2:獲取文件的輸出流
19             FileOutputStream fos = new FileOutputStream("D:\\Server\\"+time+".jpg");
20             
21             //3:將從套接字輸入流讀取的數據寫入文件的輸出流
22             byte[] bytes = new byte[1024];
23             int len = 0;
24             while((len = is.read(bytes)) != -1){
25                 fos.write(bytes, 0, len);
26             }
27             System.out.println("while之後");
28             
29             //--在這裏給客戶端反饋
30             //3.1 獲取套接字的輸出流
31             OutputStream os = cSocket.getOutputStream();
32             //3.2 發送反饋信息
33             os.write("上傳成功啦!".getBytes());
34             
35             //4:關流
36             fos.close();
37             cSocket.close();
38         } catch (Exception e) {
39         }
40     }
41 
42 }

java學習筆記之網絡編程