一、网络模型:
OSI标准模型七层架构以及其传输数据的模型如下:
传输信息的过程由上之下逐渐封装,接收过程则是由下至上逐渐拆包,每一层只解析自己独立的部分。
二、网络的机要素
1、IP
1 public class NetTest { 2 public static void main(String[] args) throws UnknownHostException { 3 //获取本地ip 4 InetAddress ip = InetAddress.getLocalHost(); 5 System.out.println(ip); 6 } 7 }
2、域名
本地ip和域名映射文件 : C:\Windows\System32\drivers\etc\hosts
当用户访问的是服务器对应的域名时候,首先会在本地该映射文件中找,如果没有,则访问第三方厂商提供的域名解析器进行解析,最终将域名解析为ip地址进行访问。如下图:
3、端口port
为了能够实现应用程序之间的通讯,引入端口来区分。例如飞秋和qq之间的通讯。
4、传输层协议
传输层协议有一下几个TCP 、UDP 、 TLS 、 DCCP 、 SCTP 、RSVP 、 PPTP,常用的有TCP和UDP。
UDP:
面向无连接;将数据及源和和目的封装成包,不需要建立连接;每一个数据包的大小限制在64kb以内;不需要连接,因此速度快;不安全(例如qq发送消息)。
TCP:
需要建立连接,形成传输通道;在连接中进行大量的数据传输;通过三次握手完成连接,是安全可靠的;同比效率较低(例如用qq传递文件)。
5、网络传输中的重要概念Soket
它是为通讯提供的一种机制;通信的两端都有Soket;网络通讯的实质就是Soket之间的通讯;数据在两个Soket之间及进行IO传输。
6、UDP
UDP传输如同码头、船、集装箱和货物一样;发送的信息如同货物,DatagramPacket就是集装箱,多大的货物就要用对应的集装箱;传输协议如同船只,soket就是码头。接收端必须要有明确的端口。然后用自己的DatagramPacket(集装箱去封装货物)。代码和步骤如下:
1 //基于UDP传输协议的多人聊天示例 2 public class UdpChat { 3 public static void main(String[] args) throws Exception { 4 DatagramSocket dsk = new DatagramSocket(); 5 DatagramSocket res = new DatagramSocket(10001);//接收方必须有固定端口 6 Send_Port send = new Send_Port(dsk); 7 Resive_Port resv = new Resive_Port(res); 8 new Thread(send).start();; 9 new Thread(resv).start();; 10 } 11 } 12 13 /* 14 * 发送端 15 */ 16 class Send_Port implements Runnable{ 17 /* 18 * 步骤: 19 * 1、创建UDP的Soket,使其具备发送能力; 20 * 2、创建及封装需要传输的数据; 21 * 3、使用Soket的send方法进行发送; 22 * 4、关闭资源。 23 */ 24 25 //该对象用于发送 26 private DatagramSocket dsk; 27 public Send_Port(DatagramSocket sp) { 28 super(); 29 this.dsk = sp; 30 } 31 @Override 32 public void run() { 33 //键盘输入文本 34 BufferedReader bf = new BufferedReader(new InputStreamReader(System.in)); 35 String line = null; 36 System.out.println("请输入:"); 37 try { 38 while((line = bf.readLine()) != null) { 39 if("886".equals(line)) { 40 System.out.println("发送方终止通话"); 41 break; 42 } 43 byte[] bt = line.getBytes(); 44 /*参数:需要传输的数据;数据长度,接收方的ip地址,接收方的端口号*/ 45 DatagramPacket packg = new DatagramPacket(bt, bt.length, InetAddress.getByName("172.16.10.255"), 10001); 46 dsk.send(packg); 47 } 48 dsk.close();//关闭资源 49 } catch (IOException e) { 50 e.printStackTrace(); 51 } 52 } 53 } 54 55 /* 56 * 接收端 57 */ 58 class Resive_Port implements Runnable{ 59 /* 60 * 步骤: 61 * 1、创建UDP的Soket,用于接收 62 * 2、创建接受包,用于接收传递来的数据,其中需要规定接收专用的集合及其大小 63 * 3、接收数据 64 * 4、关闭资源。 65 */ 66 private DatagramSocket drk; 67 //初始化参数 68 public Resive_Port(DatagramSocket drk) { 69 super(); 70 this.drk = drk; 71 } 72 @Override 73 public void run() { 74 byte[] res_byte = new byte[1024]; 75 DatagramPacket res = new DatagramPacket(res_byte , res_byte.length);//相当于集装箱。 76 while(true) { 77 try { 78 drk.receive(res); 79 String text = new String(res.getData(),0,res.getData().length); 80 if(text!=null) { 81 DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm"); 82 String date = df.format(new Date()); 83 if("886".equals(text)) { 84 System.out.println("用户:"+res.getAddress()+"退出群聊!"); 85 } 86 System.out.println(res.getAddress()+":"+text); 87 System.out.print(date); 88 } 89 } catch (IOException e) { 90 e.printStackTrace(); 91 } 92 } 93 } 94 }
7、TCP
面向连接,详情人如下:
1 public class TCPTest { 2 /** 3 * 服务端编程思想:(开启后将处于阻塞状态) 4 * 1、创建服务端Socket,监听一个明确的端口; 5 * 2、获取客户端对象(不用自己创建流) 6 * 3、根据客户端对象获取到对应的输入流,读取客户端发来数据 7 * 4、逻辑处理 8 * 5、 9 * @throws Exception 10 */ 11 public static void main(String[] args) throws Exception { 12 13 //服务端socket,监听一个端口 14 ServerSocket ss = new ServerSocket(10003); 15 Service ser = new Service(ss); 16 ser.server(); 17 } 18 } 19 20 class test{ 21 /** 22 * 客户端编程思路: 23 * 1、创建客户端Soket,明确服务端的地址和端口。 24 * 2、三次握手,建立通道,如果通道建立成功,客户端和服务器就会形成Soke IO流。 25 * 客户端的任务就是获取到Socket中的输出流将,将信息传输服务器中。 26 * 3、通过输出流发送数据 27 * 4、关闭资源 28 * 29 * 注意事项:面向连接编程首先应该先启动服务器,这样客户端才能够像服务器发送请求 30 */ 31 public static void main(String[] args) throws Exception { 32 //客户端socket,明确服务端ip和port 33 Socket s = new Socket(InetAddress.getByName("172.16.10.23"),10003); 34 Client cl = new Client(s); 35 cl.client(); 36 } 37 } 38 39 class Client{ 40 /*客户端socket*/ 41 private Socket client_socket; 42 /* 初始化参数 */ 43 public Client(Socket client_socket) { 44 super(); 45 this.client_socket = client_socket; 46 } 47 public void client() throws Exception { 48 OutputStream out = null; 49 try { 50 System.out.println("客户端开始请求资源"); 51 out = client_socket.getOutputStream(); 52 out.write("请求资源".getBytes()); 53 } catch (IOException e) { 54 throw new Exception("连接超时:"+ e); 55 }finally{ 56 out.close(); 57 } 58 } 59 } 60 61 class Service{ 62 private ServerSocket service ; 63 public Service(ServerSocket service) { 64 super(); 65 this.service = service; 66 } 67 /*阻塞状态*/ 68 public void server() throws Exception { 69 System.out.println("服务器初始化完成..."); 70 //获取客户端 71 Socket client = service.accept(); 72 if(client!=null) { 73 //从客户端中获取输入流 74 InputStream in = client.getInputStream(); 75 //读取 76 byte[] bt = new byte[1024]; 77 int line = in.read(bt); 78 String text = new String(bt,0,line); 79 String ip = client.getInetAddress().getHostAddress(); 80 System.out.println(ip+":"+text); 81 client.close(); 82 } 83 } 84 }