Java进阶之网络编程
java基础之网络编程
什么是网络编程
- 计算机网络
- 计算机网络是通过传输介质、通信设施和网络通信协议,把分散在不同地点的计算机设备互连起来,实现资源共享和数据传输的系统。网络编程就就是编写程序使联网的两个(或多个)设备(例如计算机)之间进行数据传输。
- 网络数据的交互程序,Java的网络编程主要涉及到的是Socket编程
程序架构
- C(Client)/S(Service)
- B(前端)/S()
协议
- 如同人与人之间相互交流需要遵循一定的规矩一样,计算机之间能够进行相互通信是因为他们都共同准守一定的规则,约定,即网络协议
- 网络体系结构--OSI参考模型,TCP/IP参考模型
- 常见网络协议
- TCP协议 --传输控制协议--安全可靠协议
- TCP是面向连接的传输层协议,TCP层位于IP层之上,应用层之下的中间层
- 不同机器之间经常需要可靠的连接,但是IP层不提供这样的机制,知识提供不可靠的数据包交换
- TCP协议采用字节流传输协议
- 三次握手与四次挥手
- TCP是面向连接的协议,因此每个TCP链接都有三个阶段:连接建立、数据传送、连接释放
- 第一次握手,客户机发送请求报文到服务器,等待服务器确认
- 第二次握手,服务器接收到连接请求报文,如果同意客户机连接,便向客户机发送回执确认报文
- 第三次握手,客户机收到服务器的确认报文回执后,想服务器给出确认报文,客户端和服务器进入连接状态,完成三次握手
- 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
- 第一次挥手,TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送
- UDP协议 --非安全可靠协议
- HTTP协议 --超文本传输协议
- TCP协议是传输控制协议,UDP协议是用户数据报协议,两者都是传输层的协议,主要区别在于前者是可靠的,面向连接的协议,后者是不可靠的,无连接的协议。其它的区别还有,TCP协议传输速度慢,UDP常用于一次性传输比较少量数据的网络应用。
IP和端口
- IP是在网络上定义一台机器的标识,常见的IP为IPV4,IPV6
- 端口:数据连通的出入口
- IP和端口就相当于港口和码头
Java网络编程
- Socket编程主要涉及到客户端和服务器端两个方面,首先是在服务器端创建一个服务器套接字(ServerSocket),并把它附加到一个端口上,服务器从这个端口监听连接。端口号的范围是0到65536,但是0到1024是为特权服务保留的端口号,我们可以选择任意一个当前没有被其他进程使用的端口。
- 客户端请求与服务器进行连接的时候,根据服务器的域名或者IP地址,加上端口号,打开一个套接字。当服务器接受连接后,服务器和客户端之间的通信就像输入输出流一样进行操作。
- 栗子:服务器端代码-TCP连接
import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; public class NetworkServer { public static void main(String[] args) throws IOException { ServerSocket server = new ServerSocket(9999); System.out.println("等待客户端连接"); Socket sSocket = server.accept();//孔 System.out.println("连接完毕"); //服务器向客户端发送消息 写 输出 SocketOutputStream Fi while(true){ OutputStream os = sSocket.getOutputStream(); PrintWriter writer = new PrintWriter(os); Scanner sc = new Scanner(System.in); System.out.println("你要说啥?"); String message = sc.nextLine(); System.out.println("你说:"+message); writer.println(message); writer.flush(); InputStream is = sSocket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String message1 = br.readLine(); System.out.println("客户端说:"+message1); if(message.equals("拜拜") || message1.equals("拜拜")){ break; } } } }
- 栗子:客户端代码-TCP连接
import java.io.*; import java.net.Socket; import java.util.Scanner; public class NetworkClient { public static void main(String[] args) throws IOException { Socket cSocket = new Socket("127.0.0.1",9999); //流 while(true){ InputStream is = cSocket.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String message = br.readLine(); System.out.println("服务器说:"+message); OutputStream os = cSocket.getOutputStream(); PrintWriter writer = new PrintWriter(os); Scanner sc = new Scanner(System.in); System.out.println("你要说啥?"); String message1 = sc.nextLine(); System.out.println("你说:"+message1); writer.println(message1); writer.flush(); if(message1.equals("拜拜") || message.equals("拜拜")){ break; } } } }
- 相对于TCP,UDP在传输多次,大量数据的时候,会有丢包的现象
- 发送方
import java.io.IOException; import java.net.*; public class NetworkReceiveUDP{ public static void main(String[] args) throws IOException { DatagramSocket datagramSocket = new DatagramSocket(); String s = "你好"; byte[] bs = s.getBytes(); DatagramPacket packet = new DatagramPacket(bs,bs.length, InetAddress.getByName("127.0.0.1"),9999); for (int i = 0;i<1000000;i++){ datagramSocket.send(packet); } } }
-
- 接收方
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class TestSend { public static void main(String[] args) throws IOException { DatagramSocket datagramSocket = new DatagramSocket(9999); byte[] b = new byte[24]; DatagramPacket datagramPacket = new DatagramPacket(b,0,b.length); int count = 0; while (true){ datagramSocket.receive(datagramPacket); String s = new String(b,0,datagramPacket.getLength()); System.out.println(s); count++; System.out.println(count); } } }