网络编程
一、网络的七层模型
从下往上依次是物理层(电路,布线)-数据链路层(交换机)-网络层(tcp/ip,路由器)-传输层-会话层-表示层(编码,解码,加密,解密,压缩,解压缩)-应用层(http),但是tcp/ip模型是网络接口层-网络层-传输层-应用层
二、三次握手和四次挥手
1. 三次握手:
(1) 客户端向网络服务器端发送请求 (你在吗?)
(2) 服务器端回应客户端的请求 (我在)
(3) 服务器端向客户端发送请求 (我在,你在吗?)
2. 四次挥手
(1) 客户端向服务器端发送请求 (我要离开了)
(2) 服务器端回应客户端 (嗯)
(3) 客户端再次向服务器端发出请求 (我真的要离开了)
(4) 服务器端回应客户端 (嗯,走好)
三、常用的InetAddress的主要函数
1 package com.study.test; 2 3 import java.io.IOException; 4 import java.net.InetAddress; 5 6 public class NetTest { 7 8 public static void main(String[] args) throws IOException { 9 InetAddress ia = InetAddress.getLocalHost(); 10 System.out.println(ia.getHostName());// 获得本机名字 11 System.out.println(InetAddress.getByName(ia.getHostName()));// 通过名字查询到ip地址 12 byte[] b = new byte[4]; 13 b = ia.getAddress();// 以字节的形式存放的地址 14 System.out.println(ia.getHostAddress());// 以字符串形式列出的ip地址 15 16 } 17 18 }
输出结果:
xx
xx/192.168.152.1
192.168.152.1
四、tcp编程服务端与客户端通讯
1. 服务端代码
1 package com.study.test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.InputStreamReader; 6 import java.io.OutputStream; 7 import java.net.ServerSocket; 8 import java.net.Socket; 9 import java.util.Scanner; 10 11 /** 12 * 编程实现tcp通讯服务端 13 * 14 * @author THINKPAD 15 * 16 */ 17 public class NetServer { 18 19 public static void main(String[] args) throws IOException { 20 // 1 建立服务端socket 21 ServerSocket ss = new ServerSocket(60000);// 1、有效没有指明ip地址,则本网卡对应的所有ip地址全部 22 // 通信的时候一定要有目标端口号,如果没有,则补救bind 23 // ServerSocket ss=new ServerSocket(); 24 // SocketAddress sa=new InetSocketAddress(60000); 25 // ss.bind(sa); 26 // 2 进行接收连接 27 Socket s = ss.accept(); // 阻塞等待,等待三次握手 1 syn 2 ack syn 3 ack ,一旦握手成功,形成一个通道 28 System.out.println(s.getPort() + "连接进来了"); // 如果tcp每次发送信息,对方一定要确认收到的,这样可以保证数据不丢失 29 30 while (true) { 31 // 3 接收传送的信息,通过网络流/节点流 32 InputStream is = s.getInputStream(); 33 InputStreamReader isr = new InputStreamReader(is); 34 char[] cArray = new char[20]; 35 int iRead = isr.read(cArray);// 阻塞函数,一定要接收到数据 比如:in.read()一定要从键盘缓冲区获得数据,而这个等待是一定要从服务器获得数据 36 if (iRead == -1) 37 break; 38 System.out.println("得到的字节数:" + iRead);// 返回字节数 39 System.out.println("收到的信息是" + new String(cArray, 0, iRead)); 40 // 3.1 回复信息 41 OutputStream os = s.getOutputStream(); 42 Scanner sc = new Scanner(System.in); 43 String sSend = sc.nextLine(); 44 os.write(sSend.getBytes()); 45 } 46 // 4 关闭 结束之后就会发生4次挥手 1 fin ack 2 ack 3 fin ack 4 ack 47 ss.close(); 48 s.close(); 49 50 } 51 52 }
2. 客户端代码
1 package com.study.test; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.io.InputStreamReader; 6 import java.io.OutputStream; 7 import java.net.Socket; 8 import java.util.Scanner; 9 10 /** 11 * 编程实现tcp通讯的客户端 12 * 13 * @author THINKPAD 14 * 15 */ 16 public class NetClient { 17 public static void main(String[] args) throws IOException { 18 // 1 建立客户端socket ,建立一个通道 19 Socket s = new Socket("192.168.152.1", 60000); 20 while (true) { 21 // 2.1 先发送信息 22 OutputStream os = s.getOutputStream(); 23 Scanner sc = new Scanner(System.in); 24 String sSend = sc.nextLine(); 25 os.write(sSend.getBytes()); 26 27 // 2.2 接收传送的信息,通过网络流/节点流 28 InputStream is = s.getInputStream(); 29 InputStreamReader isr = new InputStreamReader(is); 30 char[] cArray = new char[20]; 31 int iRead = isr.read(cArray);// 阻塞函数,一定要接收到数据 比如:in.read()一定要从键盘缓冲区获得数据,而这个等待是一定要从服务器获得数据 32 if (iRead == -1) 33 break; 34 System.out.println("得到的字节数:" + iRead);// 返回字节数 35 System.out.println("收到的信息是" + new String(cArray, 0, iRead)); 36 } 37 // 3 关闭 结束之后就会发生4次挥手 1 fin ack 2 ack 3 fin ack 4 ack 38 s.close(); 39 40 } 41 42 }