網絡編程UDP/TCP協議
一、網絡編程三要素
IP:網絡中設備的標識,不易記憶,可用主機名
端口號:用於標識進程的邏輯地址,不同進程的標識
傳輸協議:通訊的規則常見協議:TCP,UDP
UDP
把數據打成一個數據包 , 不需要建立連接
數據包的大小有限制不能超過64k
因為無連接,所以屬於不可靠協議(可能丟失數據)
因為無連接 ,所以效率高
TCP
需要建立連接,形成連接通道
數據可以使用連接通道直接進行傳輸,無大小限制
因為有鏈接,所以屬於可靠協議
因為有鏈接,所以效率低
二、IP以及端口號
1、InetAddress類 —— 表示互聯網協議 (IP) 地址
1)此類沒有構造方法,創建對象使用方法實現
public static InetAddress getByName(String host) //參數為主機名或者IP的字符串表現形式
2)常用方法
public String getHostAddress() 獲取IP
public String getHostName() 獲取主機名
2、cmd IP查詢
127.0.0.1 本地回環地址 用來做一些本地測試 不走交換機
ping IP地址 用來檢測本機是否可以和指定的IP地址的計算機可以進行正常通訊
ipconfig /all 用來查看IP地址
getmac 用來獲取mac地址
3、端口號 —— 邏輯端口
用來標示我們的計算機上的進程(正在運行的程序),端口號的有效範圍應該是 0-65535,其中0-1024被系統占用或者保留
三、UDP協議
1、DatagramSocket類 —— 此類表示用來發送和接收數據報包的套接字
1)構造方法:
public DatagramSocket()
public DatagramSocket(int port) //參數port 端口號
public DatagramSocket(int port,InetAddress laddr) //參數laddr IP對象
2)常用方法:
public void close()關閉此數據報套接字
public void send(DatagramPacket p)
public void receive(DatagramPacket p) 接收數據報包
public InetAddress getInetAddress() 返回此套接字連接的地址。如果套接字未連接,則返回 null。
2、DatagramPacket類 —— 此類表示數據報包
1)構造方法:
public DatagramPacket(byte[] buf,int length)
//參數 buf:保存傳入數據報的緩沖區 length:一次要讀取的長度
public DatagramPacket(byte[] buf,int length,InetAddress address,int port)
//參數 buf:包數據 length:包長度 address:目的IP port:目的端口號
2)解析數據:
public byte[] getData()返回用來接收或發送數據的緩沖區
public int getLength()返回將要發送或接收到的數據的長度
3、使用UDP傳輸數據
1)客戶端:
public class SentDemo { public static void main(String[] args) throws IOException { InetAddress ip = InetAddress.getByName("接收端ip的字符串變現形式"); DatagramSocket ds = new DatagramSocket(); byte[] buf = "abc".getBytes(); DatagramPacket dp = new DatagramPacket(buf, buf.length, ip, 6666); //端口號不能定義成0-1024 ds.send(dp); ds.close(); } }
2)接收端:
public class ReceiveDemo { public static void main(String[] args) throws IOException { DatagramSocket ds = new DatagramSocket(6666); byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); System.out.println(new String(dp.getData(),0,dp.getLength())); ds.close(); } }
四、TCP協議 —— 使用管道輸入輸出流傳輸數據
1、服務器端
1)創建TCP通訊協議服務器端對象
ServerSocket ss = new ServerSocket("端口號");
2)監聽客戶端
Socket sk = ss.accept();
3)獲取管道輸入流對象
InputStream is = sk.getInputStream();
4)讀取數據 //在使用管道輸入流while循環接收數據的時候,不能以-1作為讀取完畢的判定條件
//一般循環讀取數據時,在客戶端調用shutdownOutput()方法,服務端自動跳出循環
byte[] buf = new byte[1024 * 8];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
5)釋放資源
ss.close(); //一般服務器不用關閉
2、客戶端
1)創建TCP通訊協議客戶端對象
Socket sk = new Socket("服務端IP","服務端端口號");
2)獲取管道流輸出對象
OutputStream os = sk.getOutputStream();
3)寫數據
os.write("需要傳輸的內容".getBytes());
4)釋放資源
sk.close();
3、服務端反饋
服務端:
1)創建TCP通訊協議服務器端對象
2)監聽客戶端
3)獲取管道輸入流對象
4)讀取數據
5)獲取管道輸出流對象
OutputStream os = sk.getOutputStream();
6)反饋信息
os.write("已收到".getBytes());
客戶端:
1)創建TCP通訊協議客戶端對象
2)獲取管道流輸出對象
3)寫數據
4)獲取管道輸入流對象
InputStream is = sk.getInputStream();
4)接收反饋信息
byte[] buf = new byte[1024 * 8];
int len = is.read(buf);
System.out.println(new String(buf,0,len));
5)釋放資源
4、shutdownOutput()方法
當客戶端發送文件時,發送完畢後調用shutdownOutput()方法,服務端就會收到,停止接收;
sk.shutdownOutput();
5、TCP服務端多線程改進
public class TCPServerDemo { public static void main(String[] args) throws IOException { ServerSocket ss = new ServerSocket(9527) ; //循環監聽客戶端 while(true){ Socket sk = ss.accept() ; // 開啟線程 new Thread(new TCPServerThread(sk)).start() ; } } }
public class TCPServerThread implements Runnable { private Socket sk ; public TCPServerThread(Socket sk){ this.sk = sk ; } @Override public void run() { try { BufferedReader br = new BufferedReader(new InputStreamReader(sk.getInputStream())) ; BufferedWriter bw = new BufferedWriter(new FileWriter("a.java")) ; // 一次讀取一行 String line = null ; while((line = br.readLine()) != null){ bw.write(line) ; bw.newLine() ; bw.flush() ; } try { Thread.sleep(100) ; } catch (InterruptedException e) { e.printStackTrace(); } // 給客戶端端反饋 // 獲取輸出流對象 OutputStream out = sk.getOutputStream() ; out.write("上傳文件成功!".getBytes()) ; } catch (Exception e) { e.printStackTrace() ; } } }
網絡編程UDP/TCP協議