1.1、OIS參考模型
1.2、TCP/ip參考模型
1.3、網絡通訊要素
IP地址:IPV4/IPV6
端口號:0-65535,一般0-1024,都被系統占用,MySQL:3306,Oracle:1521
傳輸協議:TCP/UDP
2.1、InetAddress 主機對象
IP 地址是 IP 使用的 32 位或 128 位無符號數字,它是一種低級協議,UDP 和 TCP 協議都是在它的基礎上構建的
2.2、示例
import java.net.*;class IPDemo { public static void main(String[] args) throws Exception { //getLoaclHostAddress(); getAllByName(); } /* 獲取本機的IP和主機名 */ public static void getLoaclHostAddress() throws Exception { //返回本地主機 InetAddress ia=InetAddress.getLocalHost(); System.out.PRintln(ia.toString()); //主機名 String hostName=ia.getHostName(); //IP地址 String ip=ia.getHostAddress(); System.out.println("hostName="+hostName+".....ip="+ip); } /* 獲取163或者百度的所有IP地址集合 */ public static void getAllByName() throws Exception { //獲取淘寶的主機數組 InetAddress [] ia=InetAddress.getAllByName("www.163.com"); for(InetAddress i:ia) { //輸出主機IP地址 System.out.println("IP:"+i.getHostAddress()); System.out.println("Name:"+i.getHostName()); } }}
3.1、概述
4.1、Socket
Socket就是為網絡服務提供的一種機制
通信兩端都有Socket
網絡通信其實就是Socket間的通信
數據在兩個Socket間通過IO通信
五、UDP
5.1、概述
此類表示用來發送和接收數據報包的套接字。
構造方法摘要 | |
---|---|
DatagramSocket() 構造數據報套接字并將其綁定到本地主機上任何可用的端口。 | |
protected | DatagramSocket(DatagramSocketImpl impl) 創建帶有指定 DatagramSocketImpl 的未綁定數據報套接字。 |
DatagramSocket(int port) 創建數據報套接字并將其綁定到本地主機上的指定端口。 | |
DatagramSocket(int port, InetAddress laddr) 創建數據報套接字,將其綁定到指定的本地地址。 | |
DatagramSocket(SocketAddress bindaddr) 創建數據報套接字,將其綁定到指定的本地套接字地址。 |
此類表示數據報包。
數據報包用來實現無連接包投遞服務。每條報文僅根據該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。不對包投遞做出保證。
構造方法摘要 | |
---|---|
DatagramPacket(byte[] buf, int length) 構造 DatagramPacket ,用來接收長度為 length 的數據包。 | |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) 構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號。 | |
DatagramPacket(byte[] buf, int offset, int length) 構造 DatagramPacket ,用來接收長度為 length 的包,在緩沖區中指定了偏移量。 | |
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 構造數據報包,用來將長度為 length 偏移量為 offset 的包發送到指定主機上的指定端口號。 | |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) 構造數據報包,用來將長度為 length 偏移量為 offset 的包發送到指定主機上的指定端口號。 | |
DatagramPacket(byte[] buf, int length, SocketAddress address) 構造數據報包,用來將長度為 length 的包發送到指定主機上的指定端口號。 |
5.2、UDP發送端
/*發送端1.創建UDP服務,通過DatagramSocekt,2.創建發送的數據,并封裝為數據包,DatagramPacket3.發送send4.關閉DatagramSocekt資源*/import java.net.*;class UdpSend { public static void main(String[] args) throws Exception { //1.創建UDP服務,通過DatagramSocekt, DatagramSocket ds=new DatagramSocket(); //2.創建發送的數據,并封裝為數據包,DatagramPacket String say="udp數據!"; byte [] buf = say.getBytes(); InetAddress ia=InetAddress.getByName("localhost"); int port =9898; DatagramPacket dp=new DatagramPacket(buf,buf.length,ia,port); //3.發送send ds.send(dp); //4.關閉DatagramSocekt資源 ds.close(); }}
5.3、UDP接收端服務端
/*接收端,服務端1.創建UDP,Socket服務對象,DatagramSocket,設置商品2.創建數據服包對象DatagramPacket包,接收數據報包3.接收receive,到數據包在4.通過數據報包,獲取其中的數據如IP,數據和端口5.解析數據轉化為字符串,并打印6.關閉資源*/import java.net.*;class UdpReceive { public static void main(String[] args) throws Exception { //1.創建UDP,Socket服務對象,DatagramSocket,設置端口 DatagramSocket ds=new DatagramSocket(9898); //2.創建數據服包對象DatagramPacket包,接收數據報包 //接收內容的字節數據 byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); //3.接收receive,到數據包在 ds.receive(dp); //4.通過數據報包,獲取其中的數據如IP,數據和端口 //IPD String ip=dp.getAddress().getHostAddress(); //主機名 String hostname=dp.getAddress().getHostName(); //數據 String data=new String(dp.getData(),0,dp.getLength()); //5.解析數據轉化為字符串,并打印 System.out.println(ip+":"+hostname+":"+data); //6.關閉資源 ds.close(); }}
5.4、鍵盤錄入
/*發送端鍵盤錄入*/import java.net.*;import java.io.*;class UdpSend2 { public static void main(String[] args) throws Exception { //建立UDPSocket服務對象DatagramSocket DatagramSocket ds=new DatagramSocket(); //主機對象 InetAddress ia=InetAddress.getByName("localhost"); int port=10001; //錄入數據,字符流,鍵盤錄入 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); String line=null; while((line=br.readLine())!=null) { if("886".equals(line)) break; //封裝為數據報包 byte [] buf=line.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,ia,port); //發送 ds.send(dp); } //關閉 br.close(); ds.close(); }}
/*接收端一直開啟*/import java.net.*;class UdpRece2 { public static void main(String[] args) throws Exception { //建立DatagramSocket對象服務,并指定端口 DatagramSocket ds=new DatagramSocket(10001); while(true) { //接收數據報包 byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); //接收 ds.receive(dp); //獲取數據報中的數據 String ip=dp.getAddress().getHostAddress(); String data=new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+data); } }}
5.5、示例
package com.pb.demo1;/*簡單聊天工具*///發送端import java.net.*;import java.io.*;class Send implements Runnable{ private DatagramSocket ds; public Send( DatagramSocket ds) { this.ds=ds; } //線程重寫方法 public void run() { try {//接收鍵盤錄入 BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); InetAddress ia=InetAddress.getByName("192.168.2.255"); int port =10002; String line=null; while ((line=br.readLine())!=null) { if("886".equals(line)) break; //封裝數據 byte[] buf=line.getBytes(); DatagramPacket dp=new DatagramPacket(buf,buf.length,ia,port); //發送 ds.send(dp); } } catch (Exception e) { throw new RuntimeException("發送失敗!"); } } }//接收端class Rece implements Runnable{ private DatagramSocket ds; public Rece( DatagramSocket ds) { this.ds=ds; } //線程重寫方法 public void run() { try { while (true) { //接收 byte[] buf=new byte[1024]; DatagramPacket dp=new DatagramPacket(buf,buf.length); ds.receive(dp); //通過數據報獲取信息 String ip=dp.getAddress().getHostAddress(); String data=new String(dp.getData(),0,dp.getLength()); //輸出 System.out.println(ip+":"+data); } } catch (Exception e) { throw new RuntimeException("接收失敗!"); } } }class ChatDemo { public static void main(String[] args) throws Exception { //發送 DatagramSocket send=new DatagramSocket(); //接收 DatagramSocket rece=new DatagramSocket(10002); new Thread(new Send(send)).start(); new Thread(new Rece(rece)).start(); }}
5.1、概述
5.2、TCP傳輸一次-簡單使用
/*TCP傳輸1.TCP分客戶端與服務端2.客戶端:Socket 服務端:ServerSocket*//*客戶端:Socket() 通過系統默認類型的 SocketImpl 創建未連接套接字 Socket(InetAddress address, int port) 創建一個流套接字并將其連接到指定 IP 地址的指定端口號。 Socket(InetAddress host, int port, boolean stream) 已過時。 Use DatagramSocket instead for UDP transport. Socket(InetAddress address, int port, InetAddress localAddr, int localPort) 創建一個套接字并將其連接到指定遠程地址上的指定遠程端口。 Socket(Proxy proxy) 創建一個未連接的套接字并指定代理類型(如果有),該代理不管其他設置如何都應被使用。 protected Socket(SocketImpl impl) 使用用戶指定的 SocketImpl 創建一個未連接 Socket。 Socket(String host, int port) 創建一個流套接字并將其連接到指定主機上的指定端口號。 Socket(String host, int port, boolean stream) 已過時。 使用 DatagramSocket 取代 UDP 傳輸。 Socket(String host, int port, InetAddress localAddr, int localPort) 創建一個套接字并將其連接到指定遠程主機上的指定遠程端口。 通過構造方法可以發現:Socket對象,在建立時,就可以去連接指定主機因為Tcp是面向連接的,所以在連接成功,形成通路后,在該通道進行數據的傳輸步驟:1.創建客戶端Socket服務,指定主機與端口2.獲取Socket流,socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流3.發送數據4.關閉socket服務*/import java.net.*;import java.io.*;class TcpClient{ public static void main(String[] args) throws Exception { //1.創建客戶端Socket服務,指定主機與端口 Socket s=new Socket("localhost",10003); //2.獲取Socket流,socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流 OutputStream os=s.getOutputStream(); //3.發送數據 String say="Tcp客戶端發送,測試數據!"; os.write(say.getBytes()); //4.關閉socket服務 s.close(); }}/*步驟:1.創建服務端Socket服務,指定端口2.監聽accept,并獲取Socket流,沒有連接,這個方法是阻塞工的3.獲取對應客戶端對象的socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流4.接收數據InptuStream或者發送OutputStream5.打印6.(可選一般不關閉)關閉socket服務*/class TcpServer{ public static void main(String[] args) throws Exception { //1.創建服務端Socket服務,指定端口 ServerSocket ss=new ServerSocket(10003); //2.監聽accept,并獲取Socket流,沒有連接,這個方法是阻塞工的 Socket s=ss.accept(); //3.獲取對應客戶端對象的socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流 //4.接收數據InptuStream或者發送OutputStream InputStream is=s.getInputStream(); //獲取客戶端IP String ip=s.getInetAddress().getHostAddress(); //設置緩沖區 byte[] buf=new byte[1024]; //把數據讀取到緩沖區中 int len=is.read(buf); //轉換為字符串 String data=new String(buf,0,len); //5.打印 System.out.println(ip+"........"); System.out.println(data); //6.(可選一般不關閉)關閉socket服務 s.close(); ss.close(); }}
5.3、SocetKet接收與返回
/*客戶端給服務端發送數據服務端收到后給客戶端反饋信息客戶接收反饋數據*//*步驟:1.創建客戶端Socket服務,指定主機與端口2.獲取Socket流,socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流3.發送數據4.關閉socket服務*/import java.net.*;import java.io.*;class TcpClient2 { public static void main(String[] args) throws Exception { //1.建立Socekt服務并指定端口 Socket s=new Socket("localhost",10004); //2.信息 String sendInfo="客戶端發送的信息!"; //3.獲取輸出流寫到服務端 OutputStream os=s.getOutputStream(); os.write(sendInfo.getBytes()); //4.獲取輸入信息接收服務端信息 InputStream is=s.getInputStream(); byte [] buf=new byte[1024]; int len=is.read(buf); String rev=new String(buf,0,len); System.out.println("服務端反饋的信息:"+rev); s.close(); }}/*步驟:1.創建服務端Socket服務,指定端口2.監聽accept,并獲取Socket流,沒有連接,這個方法是阻塞工的3.獲取對應客戶端對象的socket.getXXX(InputStream或者OutputStream,并封裝為字符流或者字節流4.接收數據InptuStream或者發送OutputStream5.打印6.(可選一般不關閉)關閉socket服務*/class TcpServer2{ public static void main(String[] args) throws Exception { //建立服務端ServerSocket數據 ServerSocket ss=new ServerSocket(10004); //獲取客戶端對象accept, Socket s=ss.accept(); //獲取輸入流對象接收客戶端信息 InputStream is=s.getInputStream(); //建立緩沖區 byte [] buf=new byte[1024]; int len=is.read(buf); String clientInfo=new String(buf,0,len); //獲取IP String ip=s.getInetAddress().getHostAddress(); System.out.println(ip+"....."+clientInfo); //返回給客戶端的信息 String rel="已經收到了"; //獲取輸出流對象 OutputStream os=s.getOutputStream(); os.write(rel.getBytes()); //關閉 可選 s.close(); ss.close(); }}
5.4、綜合
/*建立一個轉換服務器客戶端輸入內容到服務器,服務把內容轉成大寫再返回給客戶端客戶端可以 不斷的進行文本輸入,當客戶端輸入over時結束*//*客戶端操作設備上的數據,可以使用IO技術并按照IO的操作規律來完成源:鍵盤錄入目的:網絡設置,網絡輸出而且操作的是文本數據,可以選擇字符流與字符緩沖流*/import java.io.*;import java.net.*;class TcpClient3{ public static void main(String[] args) throws Exception { //建立服務 Socket s=new Socket("localhost",10005); //獲取鍵盤錄入 BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); //目的發送給服務端 //BufferedWriter bwOut=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //打印流,可以接收字符流、緩沖流、字節流,第二個參數true表示自動刷新 PrintWriter out=new PrintWriter(s.getOutputStream(),true); //獲取服務端返回的信息 BufferedReader brIn= new BufferedReader(new InputStreamReader(s.getInputStream())); //鍵盤錄入數據 String line=null; //服務端返回數據 String recLine=null; //接收鍵盤錄入 while((line=br.readLine())!=null) { if("over".equals(line)) break; out.println(line); /* //將信息寫入服務端 bwOut.write(line); //增加換行 bwOut.newLine(); //刷新緩沖區 bwOut.flush(); */ //獲取取服務端返回的大寫數據 recLine=brIn.readLine(); System.out.println("服務器返回信息:"+recLine); } //結束,關資源 s.close(); }}/*服務器*/class TcpServer3{ public static void main(String[] args) throws Exception { //建立服務端對象 ServerSocket ss=new ServerSocket(10005); //獲取客戶端Socket對象 Socket s=ss.accept(); String ip=s.getInetAddress().getHostAddress(); System.out.println(ip+"...."); //獲取客戶端流對象 BufferedReader brIn= new BufferedReader(new InputStreamReader(s.getInputStream())); //BufferedWriter bwOut=new BufferedWriter(new OutputStreamWriter(s.getOutputStream())); //打印流,可以接收字符流也可以接收字節流,加true自動刷新 PrintWriter out=new PrintWriter(s.getOutputStream(),true); String line=null; while((line=brIn.readLine())!=null) { System.out.println("客戶端說:"+line); out.println(line.toUpperCase()); /* //轉換為大寫返回客戶端 bwOut.write(line.toUpperCase()); //增加換行 bwOut.newLine(); //刷新緩沖區 bwOut.flush(); */ } s.close(); ss.close(); }}/*問題:客戶端和服務端都在莫名的等待因為客戶端和服務端都在阻塞的方法,這些方法沒有讀到結束標記,那么就一直等待而導致兩端,都在等待*/
5.5、示例-TCP文件復制
/*上傳一個文件到服務器*/import java.net.*;import java.io.*;/*客戶端*/class UploadClient { public static void main(String[] args) throws Exception { //建立客戶端服務 Socket s=new Socket("localhost",10009); //上傳文件 File file=new File("d://gm.mp3"); //獲取文件名 String filename=file.getName(); //建立基本數據流將文件名發送過去 PrintWriter pw=new PrintWriter(s.getOutputStream(),true); //發送 pw.println(filename); //建立輸入流 FileInputStream fis=new FileInputStream(file); BufferedInputStream bis=new BufferedInputStream(fis); //建立流輸出 BufferedOutputStream bos=new BufferedOutputStream(s.getOutputStream()); //建立字符緩沖,接收服務端返回的提示信息 BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); int len=0; while((len=bis.read())!=-1) { bos.write(len); bos.flush(); } //關閉輸出流,增加結束標記 s.shutdownOutput(); String str=br.readLine(); System.out.println(str); bis.close(); fis.close(); s.close(); }}/*服務端*/class UploadServer { public static void main(String[] args) throws Exception { //建立服務 ServerSocket ss=new ServerSocket(10009); //獲取客戶端對象 Socket s=ss.accept(); //獲取客戶端 發送的文件名 BufferedReader br=new BufferedReader(new InputStreamReader(s.getInputStream())); String filename=br.readLine(); System.out.println("文件名:"+filename); //文件輸讀流 BufferedInputStream bis=new BufferedInputStream(s.getInputStream()); //文件輸出流 File f=new File("f://",filename); BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(f)); //輸出提示信息 PrintWriter pw=new PrintWriter(s.getOutputStream(),true); int len=0; while((len=bis.read())!=-1) { bos.write(len); bos.flush(); } pw.println("上傳成功"); bos.close(); s.close(); ss.close(); }}
新聞熱點
疑難解答