Java 12网络编程
1.网络编程入门
1.1软件结构
CS结构,全称为Client/Sever结构,是指客户端与服务端的结果,如qq 迅雷
BS结构,全称为Browser/Server结构,是指浏览器和服务端的结构,常见浏览器如谷歌或火狐。
两种架构各有优势,但无论哪种架构,都离不开网络的支持,网络编程也就是在一定的协议下,支持两个计算机的通讯程序。
1.2网络通讯协议:
含义:计算机网络中,链接和通信的规则称之为网络通信协议,它对数据的传输格式、传输速率、传输步骤等进行了统一的规定,通信双方(多台电脑或服务器)同时遵守,才能完成数据交换。
顾名思义,网络通信协议,是指通过计算机网络一遍多台计算机实现连接,位于一个网络中的计算机在连接和通信时需要遵守同一的原则。
重点学习TCP/IP协议。(传输控制协议 tansmission Control Protocol/因特网互联协议 Internet Protocol)。它是internet最基本和最广泛的协议,它定义了计算机如何选择入因特网,以及数据如何在他们之间传输的数据,内部包含一些列的用于数据通信的协议,并采用了4层的分层的模型,每一层都呼叫它的下一层所提供的协议完成自己的额需求。
说明:应用层 传输层 网络层 和链路层
1)链路层,定义物理层传输信道,通常是对某些网络连接社保的驱动协议,例如对光纤,网线提供的驱动
2)网络层,是整个tcp/ip协议的核心,它主要用于将传输的数据进行分组,将分组的数据发送至目标计算机或者网络。
3)传输层,主要使用网络程序进行通信,在进行网络通信时, 可以采用TCP协议,也可以采用UDP协议。
4)应用层,主要负责应用程序的协议,例如HTTP协议,FTP协议。
1.3 网络通信协议的分类,也就是传输层的分类
通信协议极其复杂,java.net包中包含的类和接口,他们提供低层次的通信细节,我们可以直接使用这些类和接口,来专注于网络程序的开发,而不考虑通信的细节
UDP 用户数据报协议 ,效率高,但是不安全。
其中 数据报是datagram,网络传输的基本单位
面向无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接,简单来说,当一台计算机向另一台发送数据时,发送端不会确认接收端是否存在,就会发送数据。比如qq发信息。
UDP特点 数据被限制在64Kb以内,超出就不能发送了
不问目标是否存在,因此可能存在丢失
UDP因协议资源消耗小,通信效率高,所以通常都会用于音频、视频和普通数据的传输例如 视频会议都用udp协议,因为这种情况下即便偶尔丢失一两个数据报,也不会对接收结果产生太大影响。
TCP 传输控制协议 :效率低,但是安全
面向连接的通信协议,即传输数据前,在发送端和接受端进行逻辑连接,它提供了两台计算机之间可靠无差错的数据传输。在TCP连接中,必须要明确客户端和服务器端,由客户端向服务端发起连接请求,每次连接的创建都需要经过三次握手。
第一次:客户端向服务端发出连接请求,等待服务器的确认
第二次L服务器向客户端发送一个响应,通知客户端收到了连接请求
第三次,客户端再次向服务端发送确认消息,确认连接,整个交互过程如下图所示。
TCP协议可以保证传输数据的安全,所以广泛用于下载文件、浏览网页等
一款通信的软件,可能同时启动使用udp和tcp协议,例如飞秋,它发信息是udp,发文件是tcp
1.4 网络编程的三要素 协议 IP地址 端口号
协议
也就是之前学习的内容,tcp或者udp
IP地址
指的是互联网协议地址即 internet Protocol Address,俗称IP,IP地址用来给一个网络中的计算机设备做唯一的编号,假如我们把个人电脑比作一台电脑,那么IP地址相当于电话号码。
IPv4:4个字节的32位的二进制数字,a.b.c.d其中abcd均由10进制数表示,约42亿个。
IPv6:8组16字节的16 进制数组成的128位。
常用命令
查看本机IPI地址 ipconfig
检查网络是否连接 ping 空格 ip地址
特殊IP地址 本机IP地址:127.0.0.1 localhost
1、localhost等于127.0.0.1,不过localhost是域名,127.0.0.1是IP地址。
2、localhost和127.0.0.1不需要联网,都是本机访问。
3、本机IP需要联网,本机IP是本机或外部访问, 本机 IP 就是本机对外放开访问的IP地址,这个网址就是与物理网卡绑定的IP地址。
端口号
端口号是逻辑端口,是无法直接知道的,是通过网络软件查看端口号的,一旦软件打开,操作系统将给与软件随机分配一个端口号。
端口号是由两个字节组成。0-65535之间
1 1024之前的端口号不可以用
2 网络软件的端口号不能重复,分配不可重复(理解为门牌号)
3 常用的网络端口号 80 即可 www.baidu.com:80
mysql:3306 oracle:1251 Tomcat服务器:8080
80是HTTP协议的默认端口,8080是Tomcat服务器的默认端口
2.TCP的通信程序
TCP通信是指使用TCP协议进行通信的程序,实现两台计算机的数据交互,通信的两端,要严格区分客户端Client和服务端Server。
一般而言,客户端机器配置较低,服务端的机器较好。
2.1两端通信的步骤
- 服务端程序,需要实现启动,等待客户端的连接
- 客户端主动连接服务器端,连接成功才能通信,服务端不可以直接连接客户端。
2.2 java中,提供了两个类用于实现TCP协议:tcp是面向连接的通信。
- 客户端:java.net.Socket类表示,创建Socket对象,向服务器端发出连接请求,服务端响应请求,两者建立连接开始通信
- 服务端:java.net.ServerSocket类表示,创建SeverScoket对象,相当于开启一个服务,并等待客户端的连接。
- 客户端与服务端的两者之间对象,就是IO对(字节流)象。字节流对象。
但客户端过多时,都可以与服务器端开展交流,因此服务端需要明确两件事
- 多个客户端可以和服务器进行交互,服务器必须明确和哪个客户端进行教务,方法是服务器有个方法叫accept客户端获取到请求的客户端对象。
- 多个客户端可以和服务器进行交互,需要多个IO流对象,由于服务器没有IO流对象,但可以获取到请求的客户端对象Socket使用每个客户端Socket中提供的IO流与客户端进行交流。
2.3 接下来用java程序实现下TCP端、
tcp通信的客户端:向服务器发送连接请求,给服务器发送数据,读取服务器回写的数据,表示客户的类:java.net.Socket:此类实现客户端套接字(套接字的含义是包含IP地址和端口号的网络单位),套接字是两台机器之间通信的端点。
构造方法:
Socket(String host, int port) 创建一个流套接字并将其连接到指定主机上的指定端口号。String host:服务器主机的名称/服务器的IP地址
int port:服务器的端口号
成员方法:客户端和服务器端进行交互,需要使用流对象,因此必须有成员方法,且是字节流,所以要用流获取
OutputStream getOutputSream() 返回此套接字的输出流
InputStream getInputStream() 返回此套接字的输入流;
void Closed()关闭是否此套接字
实现步骤:
1)创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号‘
2)使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象。
3)使用网络字节输出流对象 OutputSream中的方法Write,给服务器发送数据;
4)使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象。
5)使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据;
6)释放socket对象即可(流都是它的)
注意事项:
1)客户端和服务端的交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象
2)当我们创建客户端对象的时候,就会去请求服务器和服务器经过3次握手,建议链接通路。这时如果服务器没有启动,那么就会抛出异常。如果服务器启动,就可以进行交互了。
服务器端的实现步骤
1)创建服务器ServerSocket对象和系统要指定的端口号
2)使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket
3)使用Socket对象中的方法getInputStream获取网络字节输入流InputStream()对象
4)使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据
5)使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream()对象
6)使用网络字节输出流OutputStream()对象中的方法Write,给客户端回写数据
7)释放资源 (Socket(客户端),serverSocket)
练习1:没有建立4/5两个步骤执行时。抛出异常:Exception in thread "main" java.net.ConnectException: Connection refused: connect 异常
1 public class Demo06 { 2 public static void main(String[] args) throws IOException { 3 //1)创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号 4 Socket socket = new Socket("127.0.0.1",8888); 5 //2)使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象。 6 OutputStream outputStream = socket.getOutputStream(); 7 //3)使用网络字节输出流对象 OutputSream中的方法Write,给服务器发送数据; 8 outputStream.write("你好服务器".getBytes()); 9 10 11 socket.close(); 12 } 13 14 }
练习2 完整版服务器
1 public class TcpServer { 2 public static void main(String[] args) throws IOException { 3 //1)创建服务器ServerSocket对象和系统要指定的端口号 4 ServerSocket server = new ServerSocket(8888); 5 //2)使用ServerSocket对象中的方法accept,获取到请求的客户端对象Socket 6 Socket accept = server.accept(); 7 //3)使用Socket对象中的方法getInputStream获取网络字节输入流InputStream()对象 8 InputStream is= accept.getInputStream(); 9 //4)使用网络字节输入流InputStream对象中的方法read,读取客户端发送的数据 10 byte[] bytes = new byte[1024]; 11 int len = is.read(bytes); 12 System.out.println(new String( bytes ,0,len)); 13 //5)使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream()对象 14 OutputStream os = accept.getOutputStream(); 15 //6)使用网络字节输出流OutputStream()对象中的方法Write,给客户端回写数据 16 os.write("收到,谢谢".getBytes()); 17 //7)释放资源 (Socket(客户端),serverSocket) 18 accept.close(); 19 server.close(); 20 } 21 }
完整版客户端
1 public class TCPClient { 2 public static void main(String[] args) throws IOException { 3 //1)创建一个客户端对象Socket,构造方法绑定服务器的IP地址和端口号 4 Socket socket = new Socket("127.0.0.1",8888); 5 //2)使用Socket对象中的方法getOutputStream()获取网络字节输出流OutputStream对象。 6 OutputStream outputStream = socket.getOutputStream(); 7 //3)使用网络字节输出流对象 OutputSream中的方法Write,给服务器发送数据; 8 outputStream.write("你好服务器".getBytes()); 9 //4)使用Socket对象中的方法getInputStream()获取网络字节输入流InputStream对象。 10 InputStream is = socket.getInputStream(); 11 12 //5)使用网络字节输入流InputStream对象中的方法read,读取服务器回写的数据; 13 byte[] bytes = new byte[1024]; 14 int len = is.read(bytes); 15 System.out.println( new String(bytes,0,len)); 16 socket.close(); 17 } 18 }
3 综合案例
3.1文件上传