首頁 Java java教程 Java之網路程式設計的使用詳解

Java之網路程式設計的使用詳解

Jun 30, 2017 am 09:57 AM
java 入門 網路程式設計

 
關鍵字:IP位址、、連接埠、UDP、DatagramPacket類別、DatagramSocket類別、TCP、ServerSocket類別、Socket類別、檔案上傳
一、基本概念
       1、基本概念
      ①MAC:MAC(Media Access Control或Medium Access Control)位址,意為媒體存取控制,或稱為實體位址、硬體位址,用來定義網路設備的位置。在OSI模型中,第三層網路層負責IP位址 ,第二層資料鏈結層則負責 MAC位址。因此一個主機會有一個MAC位址,而每個網路位址會有一個專屬於它的IP位址。
 
      ②IP位址:是指網際網路通訊協定位址(Internet Protocol Address,又翻譯為網路協定位址),是IP Address的縮寫。 IP位址是IP協定提供的一種統一的位址格式,它為網際網路上的每一個網路和每一台主機分配一個邏輯位址,以此來封鎖實體位址的差異。目前還有些ip代理軟​​體,但大部分都收費。
      
 
 
        ③連接埠:可視為裝置與外部通訊溝通的出口。
        連接埠號碼是用兩個位元組(16位元的二進位數)表示,它的取值範圍是0~65 535 ,其中0~1023之間的連接埠號碼用於以下知名的網路服務和應用,用戶的普通應用程式需要使用1024以上的連接埠號碼。連接埠分為實體連接埠和邏輯連接埠(軟體應用程式的數位識別)。

        ④TCP (Transmission Control Protocol)和UDP(User Datagram Protocol)協定屬於傳輸層協定。

        TCP協定是連結導向的通訊協議,提供IP環境下的資料可靠傳輸,它提供的服務包括資料流傳送、可靠性、有效流控、全雙工操作和多路復用。透過面向連接、端到端和可靠的資料包發送。通俗說,它是事先為所發送的資料開闢出連接好的通道,然後再進行資料發送;

         ⑤UDP是無線通訊協議,不為IP提供可靠性、流控或錯誤恢復功能。

 

         2、常見InetAddress類別的常用方法範例:
 1 public class Example1 {
 2     public static void main(String[] args) throws Exception{
 3         //创建一个表示本地主机的InetAddress对象
 4         InetAddress localAddress = InetAddress.getLocalHost(); 
 5         //获得指定主机的InetAddress对象
 6         InetAddress remoteAddress = InetAddress.getByName("www.itcast.cn");
 7         //得到IP地址的主机名。
 8         System.out.println("本机的IP地址:"+localAddress.getHostName());
 9         //获得字符串格式的原始IP地址
10         System.out.println("itcast的IP地址:"+remoteAddress.getHostAddress());
11         //判断指定的时间内地址是否可以到达
12         System.out.println("3秒是否可达:"+remoteAddress.isReachable(3000));
13        
14         System.out.println("itcast的主机名为:"+remoteAddress.getHostName());
15     }
16 }
登入後複製

執行結果:

本机的IP地址:wrt.local
itcast的IP地址:123.57.45.99
3秒是否可达:false
itcast的主机名为:www.itcast.cn
登入後複製

 

 二、UDP通訊

      1、DatagramPacket

      此類別類似於貨櫃,在建立傳送端和接收端的DatagramPacket物件時,使用的建構方法有所不同,接收端的建構方法只需要接收一個字節數組來存放接收到的數據,而發送端的構造方法不但要接收存放了發送數據的字節數組還需要製定發送端IP地址和端口號。

      DatagramPacket建構方法:

##卷和數據大小。

       ②DatagramPacket(byte[] buf,int length,InetAddress addr,int port)

       用於傳送端, 建立DatagramPacket物件時,指定了封裝資料的位元組陣列、資料大小、位元組數組、資料大小封包的目標IP位址(addr)以及連接埠號碼(port)。

       ③DatagramPacket(byte[] buf,int offset,int length)

        用於接收端,建立DatagramPacket物件時,指定了封裝資料的位元組起始組、資料大小,以及為存取端,在建立DatagramPacket物件時,指定了封裝資料的位元組起始組、資料大小,以及為位元組數位置。 offset 參數用於指定接收的資料在放入buf緩衝數組時是從offset處開始的。

        ④DatagramPacket(byte[] buf,int offset,int length,InetAddress addr,int port)

       用於傳送端, 資料大小、資料包的目標IP位址(addr)以及連接埠號碼(port)。 offset 參數用於指定發送資料的偏移量為offset,即從offset位置開始傳送資料。

TCP/IP 網路模式

 

應用層

#如HTTP、FTP、DNS

##傳輸層

如TCP、UDP

#網路層

如IP、ICMP、IGMP

鏈鋸層

如驅動程式、介面

                                                                                              DatagramPacket類中的常用方法方法聲明功能描述InetAddress  getAddress()該方法用於返回發送端或接收端的IP位址,如果發送端的DatagramPacket對象,就返回接收端的IP位址,反之,就傳回發送端的IP位址int getPort()該方法用於返回發送端或接收端的連接埠號,如果發送端的DatagramPacket對象,就返回接收端的連接埠號,反之,就傳回發送端的連接埠號碼byte[] getData()該方法用於傳回將要接收或將要傳送的數據,如果是發送端的DatagramPacket對象,就傳回將要傳送的數據,反之,就傳回接收到的資料int getLength()該方法用於傳回將要接收或將要傳送資料的長度,如果是發送端的DatagramPacket對象,就傳回將要傳送的資料長度,反之,就回傳接收到資料的長度
##

      2、DatagramSocket

      DatagramSocket類似與碼頭,實例物件就可以傳送和接收DatagramPacket資料包,在建立傳送端和接收端的DatagramSocket物件時,所使用的建構方法有所不同。

      DatagramSocket建構方法:

       ①DatagramSocket()

      收到端的Data 用於建立物件時,在建立物件時,並沒有指定連接埠號碼,此時,系統會傳送端的DatagramSocket物件時,在建立物件時,並沒有指定連接埠號,此時,指派一個沒有被其他網路程式使用的連接埠號碼。

       ②DatagramSocket(int port)

       此方法可用於建立接收端的DatagramSocket對象,可建立傳送端的DatagramSocket對象,在建立接收端的DatagramSocket對象,可建立傳送端的DatagramSocket對象,在建立接收端的DatagramSocket一個連接埠號,這樣就可以監聽指定的連接埠。

       ③DatagramSocket(int port,InetAddress addr)

       使用此建構方法在DatagramSocket時,不僅指定連接埠號碼,也指定了相關的IP位址,此情況適用於計算上有多塊網路卡的情況。                                                                                               DatagramSocket類中的常用方法方法聲明功能描述void receive(DatagramPacket p)此方法用於將接收到的資料填入DatagramPacket資料包中,在接收到資料之前會一直處於阻塞狀態,只有當接收到資料包時,該方法才會回傳。 void  send(DatagramPacket p)#此方法用於傳送DatagramPacket封包,傳送的封包中包含將要傳送的資料、資料的長度、遠端主機的IP位址和連接埠號碼void close()#關閉目前的Socket,通知驅動程式釋放為這個Socket保留的資源。
###

3、UDP 网络程序

在通信时只有接收端程序先运行,才能避免因发送端发送的数据无法接收,而造成数据丢失。示例:

 1 import java.net.DatagramPacket;
 2 import java.net.DatagramSocket;
 3 
 4 //接收端程序
 5 public class Example2 {
 6     public static void main(String[] args) throws Exception{
 7         //创建一个长度为1024的字节数组,用于接收数据
 8         byte [] buf = new byte[1024];
 9         //定义一个DatagramSocket对象,监听的端口为8954
10         DatagramSocket ds = new DatagramSocket(8954);
11         //定义一个DatagramPacket对象,用于接收数据
12         DatagramPacket dp = new DatagramPacket(buf,1024);
13         System.out.println("等待接收数据");
14         ds.receive(dp);          //等待接收数据,如果没有数据则会阻塞
15         //调用DatagramPacket的方法获得接收的消息,包括内容、长度、IP地址和端口号
16         String str = new String(dp.getData(),0,dp.getLength())
17                 +"from"+dp.getAddress().getHostAddress()+":"+dp.getPort();
18         System.out.println(str); //打印收到的信息
19         ds.close();              //释放资源
20     }
21 }
22 
23 
24 import java.net.DatagramPacket;
25 import java.net.DatagramSocket;
26 import java.net.InetAddress;
27 
28 //发送端程序
29 public class Example3 {
30     public static void main(String[] args) throws Exception {
31         //创建一个DatagramSocket对象
32         DatagramSocket ds = new DatagramSocket(3000);
33         String str = "Hello World!";     //要发送的数据
34         /*
35          * 创建一个要发送的数据包,包括发送数据,数据长度,接收端IP地址以及端口号
36          */
37         DatagramPacket dp = new DatagramPacket(str.getBytes(),str.length(),
38                 InetAddress.getByName("localhost"),8954);
39         System.out.println("发送消息");
40         ds.send(dp);                     //发送数据
41         ds.close();                      //释放资源
42     }
登入後複製

运行结果

发送消息

等待接收数据
Hello World!from127.0.0.1:3000
登入後複製

解析:发送货物(数据)前,确定到货码头是否能接收。

创建空间(数据容器)接收货物(数据),创建码头【DatagramSocket(8954)】并实时监听发货码头发货通道(端口),创建集装箱并将空间加入用于接收货物,一直等待接收货物,接收码头将货物填充到集装箱中,获取到货物信息(数据等信息)。

发送货物需要建一个码头【DatagramSocket(3000)】,码头可指定发送通道即端口(也可以不指定发送通道),将要发送货物(数据)装进集装箱(DatagramPacket

)中,并指定发送到的码头名字(IP地址或主机名)及接收通道(端口),通过码头把集装箱发出去[send()],腾出空间(close)。

三、TCP通信

1、ServerSocket

在开发TCP程序时,首先需要创建服务器端程序,其构造方法如下:

①ServerSocket()

使用该构造方法在创建ServerSocket对象时并没有绑定端口号,不能直接使用,还需要继续调用bind(SocketAddress endpoint)方法将其绑定到指定的端口上,才能正常使用。

②ServerSocket(int port)【最常用】

使用用该构造方法在创建ServerSocket对象时,就可以将其绑定到一个指定的端口号上。

③ServerSocket(int port,int backlog)

backlog 参数用于指定在服务器忙时,可以与之保持连接请求的等待客户数量,如果没有指定这个参数默认为50 。

④ServerSocket(int port,int backlog,InetAddress bindAddr)

指定了相关的IP地址,适用于计算机上有多块网卡和多个IP的情况。

ServerSocket类中的常用方法
方法声明功能描述
Socket accept()该方法用于等待客户端的连接,在客户端连接之前一直处于阻塞状态,如果有客户端连接就会返回一个与之对应的Socket对象
InetAddress getInetAddress()该方法用于返回一个InetAddress对象,该对象封装了ServerSocket绑定的IP地址
boolean isClosed()该方法用于判断ServerSocket对象是否为关闭状态,如果是关闭状态则返回true,反之则返回false
void bind(SocketAddress endpoint)该方法用于判断ServerSocket对象绑定到指定的IP地址和端口号,其中参数endpoint封装了IP地址和端口号。

2、Socket

Socket类常用构造方法:
①Socket()
使用该构造方法在创建Socket对象时,并没指定IP地址和端口号,创建对象后还需调用connect(SocketAddress endpoint)方法,才能完成与指定服务器的连接,参数endpoint封装了IP地址和端口号。
②Socket(String host,int port)
使用该构造方法在创建Socket对象时,根据参数去连接在指定IP地址和端口上运行的服务器程序,其中参数host接收的一个字符类型的IP地址。
③Socket(InetAddress addres,int port)
与第二个构造方法类似,参数address用于接收一个InetAddress类型的对象,该对象用于封装一个IP地址。
Socket类中的常用方法
方法声明功能描述
int getPort()该方法返回一个int类型对象,该对象时Socket对象与服务器端连接的端口号
InetAddress getLocalAddress()该方法用于获取Socket对象绑定的本地IP地址,并将IP地址封装成InetAddress类型的对象返回
void close()该方法用于关闭Socket连接,结束本次通信。在关闭Socket之前,应将于Socket相关的所有的输入与输出流全部关闭,这是因为一个良好的程序应该在执行完毕时释放所有的资源
IputStream getInputStream()该方法返回一个InputStream类型的输入流对象,如果该对象是由服务器端的Socket返回,就用于读取客户端发送的数据,反之,用于读取服务器端发送的数据
OutputStream getOutputStream()该方法返回一个OutputStream类型的输出流对象,如果该对象是由服务器端的Socket返回,就用于向客户端发送数据,反之,用于向服务器端发送数据
3、简单的TCP网络程序
 1 import java.io.OutputStream;
 2 import java.net.ServerSocket;
 3 import java.net.Socket;
 4 
 5 public class Example4 {
 6     public static void main(String[] args) throws Exception {
 7         new TCPServer().listen();      //创建TCPServer对象,并调用listen()方法
 8     }
 9 }
10 //TCP服务器端
11 class TCPServer{
12     private static final int PORT= 7788;//定义一个端口号
13 
14     public void listen() throws Exception{ //定义一个listen()方法,抛出一个异常
15         ServerSocket serverSocket = new ServerSocket(PORT);//创建ServerSocket对象
16         Socket client=serverSocket.accept();  //调用ServerSocket的accept()方法接收数据
17         OutputStream os = client.getOutputStream(); //获取客户端的输出流
18         System.out.println("开始与客户端交换数据");
19         os.write(("Java欢迎你!").getBytes());
20         Thread.sleep(5000);      //模拟执行其他功能占用的时间
21         System.out.println("结束与客户端交互数据");
22         os.close();
23         client.close();
24     }
25 }
登入後複製

 1 import java.io.InputStream;
 2 import java.net.InetAddress;
 3 import java.net.Socket;
 4 
 5 public class Example5 {
 6     public static void main(String[] args) throws Exception{
 7         new TCPClient().connect();//创建TCPClient对象,并调用connect()方法
 8     }
 9 }
10 //TCP客户端
11 class TCPClient{
12     private static final int PORT=7788;//服务端的端口号
13     public void connect() throws Exception{
14         //创建一个Socket并连接到给出地址和端口号的计算机
15         Socket client = new Socket(InetAddress.getLocalHost(),PORT);
16         InputStream is = client.getInputStream(); //得到接收数据的流
17         byte[] buf = new byte[1024];  //定义1024个字节数组的缓冲区
18         int len=is.read(buf);    //将数据读取到缓冲区中
19         System.out.println(new String(buf,0,len));  //将缓冲区中的数据输出
20         client.close();       //关闭Socket对象,释放资源
21     }
22 }
登入後複製

Example4 运行结果:
开始与客户端交换数据
结束与客户端交互数据

Example5 运行结果:
Java欢迎你!
登入後複製

4、TCP案例——文件上传

实现图片上传到服务器的功能。

服务端程序:

 1 import java.io.File;
 2 import java.io.FileOutputStream;
 3 import java.io.InputStream;
 4 import java.io.OutputStream;
 5 import java.net.ServerSocket;
 6 import java.net.Socket;
 7 
 8 public class Example7 {
 9     public static void main(String[] args) throws Exception{
10         ServerSocket serverSocket = new ServerSocket(10001);//创建ServerSocket对象
11         while (true){
12             //调用accept()方法接收客户端请求,得到Socket对象
13             Socket s = serverSocket.accept();
14             //每当和客户端建立Socket连接后,单独开启一个线程处理和客户端的交互
15             new Thread(new ServerThread(s)).start();
16         }
17     }
18 }
19 class ServerThread implements Runnable{
20     private Socket socket ;     //持有一个Socket类型的属性
21     public ServerThread(Socket socket){   //构造方法中吧Socket对象作为实参传入
22         this.socket=socket;
23     }
24 
25     @Override
26     public void run() {
27         String ip = socket.getInetAddress().getHostAddress(); //获取客户端的IP地址
28         int count =1;        //上传图片个数
29         try{
30             InputStream in = socket.getInputStream();
31             //创建上传图片目录的File对象
32             File parentFile =new File("/Users/adims/Downloads/upload/");
33             if (!parentFile.exists()){  //如果不存在,就创建这个目录
34                 parentFile.mkdir();
35             }
36             //把客户端的IP地址作为上传出文件的文件名
37             File file = new File(parentFile,ip+"("+count+").jpeg");
38             while (file.exists()){
39                 //如果文件名存在,则把count++
40                 file=new File(parentFile,ip+"("+(count++)+").jpeg");
41             }
42             //创建FileOutputStream对象
43             FileOutputStream fos = new FileOutputStream(file);
44             byte[] buf=new byte[1024];  //定义一个字节数组
45             int len=0;     //定义一个int类型的变量len,初始值为0
46             while ((len=in.read(buf))!=-1){   //循环读取数据
47                 fos.write(buf,0,len);
48             }
49             OutputStream out = socket.getOutputStream();  //获取服务端的输出流
50             out.write(("上传成功").getBytes());    //上传成功后向客户端写出"上传成功"
51             fos.close();                          //关闭输出流对象
52             socket.close();                       //关闭Socket对象
53         }catch (Exception e){
54               throw new RuntimeException(e);
55         }
56     }
57 }
登入後複製

客户端程序:

 1 import java.io.FileInputStream;
 2 import java.io.InputStream;
 3 import java.io.OutputStream;
 4 import java.net.InetAddress;
 5 import java.net.Socket;
 6 
 7 public class Example8 {
 8     public static void main(String[] args) throws Exception{
 9         Socket socket= new Socket(InetAddress.getLocalHost(),10001);  //创建客户端Socket对象,指定IP地址和端口号
10         OutputStream out= socket.getOutputStream();  //获取Socket的输出流对象
11         //创建FileInputStream对象
12         FileInputStream fis = new FileInputStream("/Users/adims/Downloads/WechatIMG1.jpeg");
13         byte[] buf =new byte[1024]; //定义一个字节数组
14         int len;       //定义一个int类型的变量len
15         while ((len=fis.read(buf))!=-1){    //循环读取数据
16             out.write(buf,0,len);
17         }
18         socket.shutdownOutput();      //关闭客户端输出流
19         InputStream in = socket.getInputStream();   //获取Socket的输入流对象
20         byte[] bufMsg = new byte[1024];    //定义一个字节数组
21         int num =in.read(bufMsg);          //接收服务端的信息
22         String Msg = new String(bufMsg,0,num);
23         System.out.println(Msg);
24         fis.close();                   //关闭输入流对象
25         socket.close();                //关闭Socket对象
26     }
27 }
登入後複製

需注意:shutdownOutput()方法非常重要,因为服务器端程序在while循环中读取客户端发送的数据,当读取到-1时才会结束循环,如果客户端不调用shutdownOutput()方法关闭输出流,服务器端就不会读到-1,而会一直执行while循环,同时客户端服务器端的read(byte[])方法也是一个阻塞方法,这样客户端与服务器端进入一个“死锁”状态。

以上是Java之網路程式設計的使用詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1663
14
CakePHP 教程
1419
52
Laravel 教程
1313
25
PHP教程
1263
29
C# 教程
1236
24
突破或從Java 8流返回? 突破或從Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一種強大且表達力豐富的處理數據集合的方式。然而,使用Stream時,一個常見問題是:如何從forEach操作中中斷或返回? 傳統循環允許提前中斷或返回,但Stream的forEach方法並不直接支持這種方式。本文將解釋原因,並探討在Stream處理系統中實現提前終止的替代方法。 延伸閱讀: Java Stream API改進 理解Stream forEach forEach方法是一個終端操作,它對Stream中的每個元素執行一個操作。它的設計意圖是處

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

手機上如何將XML轉換成PDF? 手機上如何將XML轉換成PDF? Apr 02, 2025 pm 10:18 PM

直接在手機上將XML轉換為PDF並不容易,但可以藉助雲端服務實現。推薦使用輕量級手機App上傳XML文件並接收生成的PDF,配合雲端API進行轉換。雲端API使用無服務器計算服務,選擇合適的平台至關重要。處理XML解析和PDF生成時需要考慮複雜性、錯誤處理、安全性和優化策略。整個過程需要前端App與後端API協同工作,需要對多種技術有所了解。

PHP與Python:了解差異 PHP與Python:了解差異 Apr 11, 2025 am 12:15 AM

PHP和Python各有優勢,選擇應基於項目需求。 1.PHP適合web開發,語法簡單,執行效率高。 2.Python適用於數據科學和機器學習,語法簡潔,庫豐富。

PHP與其他語言:比較 PHP與其他語言:比較 Apr 13, 2025 am 12:19 AM

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP與Python:核心功能 PHP與Python:核心功能 Apr 13, 2025 am 12:16 AM

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP的影響:網絡開發及以後 PHP的影響:網絡開發及以後 Apr 18, 2025 am 12:10 AM

PHPhassignificantlyimpactedwebdevelopmentandextendsbeyondit.1)ItpowersmajorplatformslikeWordPressandexcelsindatabaseinteractions.2)PHP'sadaptabilityallowsittoscaleforlargeapplicationsusingframeworkslikeLaravel.3)Beyondweb,PHPisusedincommand-linescrip

PHP:許多網站的基礎 PHP:許多網站的基礎 Apr 13, 2025 am 12:07 AM

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

See all articles