1. 网络编程相关术语
1. IP地址
- IP是互联网上的每一台计算机都有得一个唯一表示自己的标记。
- 分以下两个大类:
- IPv4:32位,分4段,0~255之间的十进制表示。使用4个8位的二进制数据表示,每8位之间使用圆点隔开,每个8位整数可以转换成一个0~255的十进制整数,因此我们一般看到的IP地址类似:192.168.1.1
- IPv6:128位,分8段,0000~FFFF的十六进制数值,冒号分割,如:1080:0:0:0:8:800:200C:417A
IP地址号段分类:A类留给政府机构,B类分配给中等规模的公司,C类分配给任意需要的人,D类用于组播(不是主播),E类用于实验,给类可容纳的地址数目不同
请写出几个你熟悉的DNS服务器地址。
Google DNS | 8.8.8.8, 8.8.4.4 |
Public DNS+ | 119.29.29.29 |
阿里 DNS | 223.6.6.6,223.5.5.5 |
百度 DNS | 180.76.76.76 |
360 DNS | 电信:101.226.4.6 联通:123.125.81.6 移动:101.226.4.6 铁通:101.226.4.6 |
3. InetAddress类表示IP地址,有两个子类
Inet4Address(IPv4)
Inet6Address(IPv6)
public static void main(String[] args) throws IOException { // 1. getLocalHost() 返回本地主机的InetAddress对象 //相当于在dos窗口输入;ipconfig 查看本机的IP配置 InetAddress ia = InetAddress.getLocalHost(); System.out.println(ia); //DESKTOP-97KGRNJ/192.168.1.29 // 2.3 getHostName()与getHostAdress()方法获得本地主机的本机名,ip地址。 System.out.println(ia.getHostName()); //DESKTOP-97KGRNJ System.out.println(ia.getHostAddress());//192.168.1.29 // 4. getByName(String host) 获取与Host相对应的InetAddress对象 InetAddress ia1 = InetAddress.getByName("DESKTOP-97KGRNJ"); System.out.println(ia1); //DESKTOP-97KGRNJ/192.168.1.29 // 5. byte[] getAddress() 返回此 InetAddress 对象的原始 IP 地址 byte[] b = ia1.getAddress(); System.out.println(Arrays.toString(b)); // [-64, -88, 1, 29] // 反验证getAddress()方法 byte[] b1 = {(byte)192,(byte)168,(byte)1,(byte)29}; InetAddress ia2 = InetAddress.getByAddress(b1); System.out.println(ia2.getHostName()); //DESKTOP-97KGRNJ // 6. boolean isReachable(int timeout) 测试主机 是否可以和 某个地址联通 //相当于在dos窗口输入:(ping+ip地址) ping 192.168.1.29 (ping www.baidu.com) boolean bool = ia2.isReachable(1000); System.out.println(bool); //true 表示可以网络联通 }
2.端口 如果把IP地址比作一间房子的房号 ,端口就是出入这间房子的许多门(窗口)。 端口号只有整数,范围是从0 到65535(2^16-1)。
同一台机器上不能有两个程序使用同一个端口,会冲突
3. URL
- 什么是URL
URL(Uniform Resource Locator)统一资源定位符,可以直接使用此类找到互联网上的资源如一个简单的网页。
一般由:协议名,资源所在主机(域名),端口,资源名等部分组成;
如:http://itsource.cn:80/class_info/java_jichu.html
- URL类中的常用方法:
- 构造方法:URL(String protocol, String host, int port, String file)
- 方法 : InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream。
- 方法 :URI toURI() 返回与此 URL 等效的 URI
URL url = new URL("https://www.taobao.com/"); //1. InputStream openStream() 打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream InputStream is = url.openStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String line; while((line =br.readLine()) != null){ System.out.println(line); // 运行结果把淘宝网站的源代码读取出来了。 } is.close();
4. URLEncoder与URLDecoder
// import java.net.URLDecoder; // import java.net.URLEncoder; 显然是两个类 //2. URLEncoder.encode() 加码 URLDecoder.decode()解码 // 注意:对已经编码的进行编码,会继续编码,对已经解码的再解码,还是原来内容 String ss = URLEncoder.encode("你好","utf-8"); System.out.println(ss); // %E4%BD%A0%E5%A5%BD String str = URLDecoder.decode("%E4%BD%A0%E5%A5%BD","utf-8"); System.out.println(str); //你好
5. Java的网络编程包括了两种通信协议:
TCP(Transmission Control Protocal) 传输控制协议
UDP(User Datagram Prptocol) 用数据包协议
TCP是面向连接的协议,因此每个TCP连接都有3个阶段:连接建立、数据传送和连接释放。
建立TCP需要三次握手才能建立,而断开连接则需要四次挥手。
第一次握手:建立连接时,客户端发送SYN包到服务器,并进入发送状态,等待服务器确认。
第二次握手:服务器收到SYN包,必须确认客户的SYN,同时自己也送一个SYN包,即SYN+ACK包,此时服务器进入接受状态。
第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK,此包发送完毕,客户端和服务器进入已建立状态,完成三次握手
TCP四次挥手过程如下:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
- TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送。
- 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1。和SYN一样,一个FIN将占用一个序号。
- 服务器关闭客户端的连接,发送一个FIN给客户端。
- 客户端发回ACK报文确认,并将确认序号设置为收到序号加1。
public class Server { //模拟服务器端 public static void main(String[] args) throws IOException { /* *1.获取服务器端对象 *2.获取服务器端输入流 *3.读取流中的数据 *4.获取服务器端输出流 *5.往输出流中写数据 *6.关闭资源 */ while(true){ ServerSocket serverSocket = new ServerSocket(6666); Socket server = serverSocket.accept(); BufferedReader br = new BufferedReader(new InputStreamReader(server.getInputStream())); String data = null; System.out.print("客户端:"); while((data = br.readLine())!= null){ System.out.println(data); } server.shutdownInput(); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(server.getOutputStream())); System.out.print("服务器说:"); String s = new Scanner(System.in).nextLine(); bw.write(s); bw.close(); br.close(); server.close(); serverSocket.close(); } } }
public class client { //模拟客户端发送数据 public static void main(String[] args) throws UnknownHostException, IOException { /* *1.获取客户端对象 *2.获取客户端输出流 *3.往流中写数据 *4.获取客户端输入流 *5.读取流中的数据 *6.关闭资源 */ while(true){ Socket client = new Socket("127.0.0.1", 6666); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(client.getOutputStream())); System.out.print("客户端说:"); String s = new Scanner(System.in).nextLine(); bw.write(s); bw.flush(); client.shutdownOutput(); BufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream())); String data = null; System.out.print("服务器端:"); while((data = br.readLine())!= null){ System.out.println(data); } br.close(); client.close(); } } }
UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。
- TCP的所有操作必须建立可靠的连接,这样会浪费很大的性能,为此UDP这种不可靠的连接出现并成为聊天工具的宠儿。
- UDP开发中使用DatagramPacket包装一条要发送的信息,之后使用DatagramSocket完成发送操作,也能够实现在两个终端之间传输数据。
//发送端 public class Send { public static void main(String[] args) throws IOException { /*1. 获取要发送的数据(信纸) * 2.将数据封装到DatagramPacket 数据包,制定要发送的地址(信封) * 3. 通过DatagramSocket对象(邮箱)的send方法发进行送 * 4.关闭数据 * */ /*构造方法 参数: 要发送的数据 发送数据多少 ip地址 端口号 * public DatagramPacket(byte buf[], int length, InetAddress address, int port) { this(buf, 0, length, address, port); }*/ String data = "今天天气如何?"; DatagramPacket dp = new DatagramPacket(data.getBytes(),data.getBytes().length,InetAddress.getLocalHost(),8989); DatagramSocket ds = new DatagramSocket(); ds.send(dp); ds.close(); } }
public class Receive { public static void main(String[] args) throws IOException { /*1.创建接受数据包的站点(DatagramSocket对象) * 2. 通过DatagramSocket对象receive()接受发送端发过来的数据包 * 3.解析得到的数据包内的数据 * 4.关闭资源 * */ DatagramSocket ds =new DatagramSocket(8989); //创建空的数据包,需要制定 空数据包 大小 byte [] b = new byte[1024]; //默认值全为 0 DatagramPacket dp = new DatagramPacket(b,b.length); ds.receive(dp); //接受的信件保存到空数据包里面 byte[] data = dp.getData();//获取dp数据包的字节数组 System.out.println("发送端发送的数据:"+new String(Arrays.copyOf(data, dp.getLength())));
ds.close(); } }
6. TCP与UDP的区别
1. 基于连接与无连接 ;
2. 对系统资源的要求(TCP较多,UDP少) ;
3. UDP程序结构较简单 ;
4. 流模式与数据报模式 ;
5. TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证(多个数据包的顺序);