在网络通信协议下,不同计算机上运行的程序进行的数据传输。计算机和计算机之间通过网络进行数据传输
可以使用在java.net包下的技术开发出常见的网络应用程序
C/S: Client/Server 客户端/服务器 在用户本地需要下载并安装客户端程序,在远程有一个服务器端程序
优点:画面精美,用户体验好
缺点:需要开发客户端,也需要开发服务端,用户需要下载和更新的时候太麻烦
B/S:Browser/Server 只需要一个浏览器,用户通过不同的网址,客户访问不同的服务器
优点:不需要开发客户端,只需要页面+服务端;用户不需要下载,打开浏览器就能使用;
缺点:如果应用过大,用户体验会受影响
设备在网络中的地址,是唯一的标识
全称:Internet Protocol,是互联网协议地址,也称IP地址,是分配给上网设备的数字标签,通俗理解:上网设备在网络中的地址,是唯一的
IPv4 IPv6
全称:Internet Protocol version 4,互联网通信协议第四版
采用32位地址长度,分成4组 2^32方个ip
点分十进制表示法:每8位表示为一个十进制数,中间用.隔开
全称:Internet Protocol version 6,互联网通信协议第六版
采用128位地址长度,分成8组
冒分十六进制表示法:将上面每一组用16进制表示,可以省略前面的0
特殊情况:如果计算出的16进制表示形式中间有多个连续的0,可以用::表示
地址分类形式:
公网地址(万维网使用)和私有地址(局域网使用)
192.168.开头的就是私有地址,范围为:192.168.0.0 -- 192.168.255.255,专门为组织机构内部使用,以此节省IP
特殊IP地址:127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机
图来自黑马程序员网课
应用程序在设备中唯一的标识
由两个字节表示的整数,取值范围:0~65535,其中0~1023之间的端口号用于一些知名的网络服务或者应用,自己使用1024以上的端口号就可以了
注意:一个端口号只能被一个应用程序使用
数据在网络中传输的规则,常见的协议有UDP,TCP,http,https,ftp
OSI参考模型:世界互联协议标准,全球通信规范,
TCP/IP参考模型(TCP/IP协议):事实上的国际标准
图来自黑马程序员网课
TCP协议:传输控制协议(Transmission Control Protocol),它是面向连接通信协议,速度慢,没有大小限制,数据安全
TCP通信协议是一种可靠的网络协议,它在通信的两端各建立一个Socket对象,通信之前要保证连接已经建立,通过Socket产生IO流来进行网络通信
图来自黑马程序员网课
客户端代码:
- package com.lazyGirl.netdemo.tcpdemo;
-
- import java.io.DataOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
-
- public class Client {
- public static void main(String[] args) throws IOException {
-
- //在创建该对象的同时会连接服务端,如果连不上,代码会报错
- Socket socket = new Socket("127.0.0.1",10086);
-
- //可以从连接通道中获取输出流
- OutputStream os = socket.getOutputStream();
- os.write("你好".getBytes());
-
- os.close();
- socket.close();
- }
- }
服务端代码:
- package com.lazyGirl.netdemo.tcpdemo;
-
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class Server {
- public static void main(String[] args) throws IOException {
-
- ServerSocket serverSocket = new ServerSocket(10086);
-
- Socket socket = serverSocket.accept();
-
- // InputStream inputStream = socket.getInputStream();
- // InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
- // BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
-
-
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
-
- int b;
- while ((b = br.read()) != -1) {
- System.out.print((char) b);
- }
-
- socket.close();
- serverSocket.close();
-
- }
- }
输出:
UDP协议:用户数据报协议(User Datagram Protocol),它是面向无连接通信协议,速度快,有大小限制,一次最多发送64K,数据不安全,易丢失数据
图来自黑马程序员网课
UDP的三种通信方式:
单播:
组播: 组播地址:224.0.0.0 ~ 239.255.255.255 其中224.0.0.0 ~ 224.0.0.255为预留的组播地址
接收端1:
- package com.lazyGirl.netdemo.udpdemo;
-
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.InetAddress;
- import java.net.MulticastSocket;
-
- public class ReceiveMessageDemo {
- public static void main(String[] args) throws IOException {
-
- MulticastSocket ms = new MulticastSocket(10086);
-
- InetAddress group = InetAddress.getByName("224.0.0.1");
- ms.joinGroup(group);
- byte[] buf = new byte[1024];
- DatagramPacket dp = new DatagramPacket(buf, buf.length);
- ms.receive(dp);
-
- byte[] data = dp.getData();
- int len = data.length;
- String ip = dp.getAddress().getHostAddress();
- String name = dp.getAddress().getHostName();
-
- System.out.println("ip: " + ip + " name: " + name + " len: " + len + " data: " + new String(data));
-
- ms.close();
-
- }
- }
发送端:
- package com.lazyGirl.netdemo.udpdemo;
-
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.InetAddress;
- import java.net.MulticastSocket;
-
- public class SendMessageDemo {
- public static void main(String[] args) throws IOException {
-
- MulticastSocket ms = new MulticastSocket();
-
- String s = "hello";
- byte[] buf = s.getBytes();
- InetAddress addr = InetAddress.getByName("224.0.0.1");
- int port = 10086;
-
- DatagramPacket dp = new DatagramPacket(buf, buf.length, addr, port);
- ms.send(dp);
- ms.close();
-
-
- }
- }
输出:
两个接收端都接收到了消息
图来自黑马程序员网课
广播:255.255.255.255
将上面的地址改成255.255.255.255即实现该局域网内所有主机都收到消息
ipconfig: 查看本机ip地址
ping: 检查网络是否连通
接收端:
- package com.lazyGirl.netdemo;
-
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.InetAddress;
- import java.net.SocketException;
-
- public class ReceiveMessageDemo {
- public static void main(String[] args) throws IOException {
-
-
- //必须指定端口,且跟发送端口一致
- DatagramSocket socket = new DatagramSocket(10086);
-
-
- byte[] buf = new byte[1024];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
- socket.receive(packet);
-
- byte[] data = packet.getData();
- int len = packet.getLength();
- InetAddress address = packet.getAddress();
- int port = packet.getPort();
-
- System.out.println("data " + new String(data,0,data.length));
- System.out.println("address " + address.getHostAddress());
- }
- }
receive函数会阻塞
发送端:
- package com.lazyGirl.netdemo;
-
- import java.io.IOException;
- import java.net.*;
-
- public class SendMessageDemo {
- public static void main(String[] args) throws IOException {
-
- DatagramSocket socket = new DatagramSocket();
-
- String str = "hello";
- byte[] buf = str.getBytes();
-
- InetAddress address = InetAddress.getByName("192.168.1.111");
-
- int port = 10086;
- DatagramPacket packet = new DatagramPacket(buf, buf.length, address, port);
-
- socket.send(packet);
-
- socket.close();
- }
- }
输出:
聊天室:
发送端:
- package com.lazyGirl.netdemo.netcase1;
-
- import java.io.IOException;
- import java.net.*;
- import java.util.Scanner;
-
- public class SendMessageDemo {
- public static void main(String[] args) throws IOException {
-
- DatagramSocket socket = new DatagramSocket();
-
- Scanner scanner = new Scanner(System.in);
- while (true) {
- System.out.println("Enter your message");
- String message = scanner.nextLine();
-
- if ("886".equals(message)) {
- break;
- }
-
- byte[] data = message.getBytes();
-
- InetAddress address = InetAddress.getByName("lazyGril");
-
- int port = 10086;
-
- DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
-
- // System.out.println("Sending Message");
-
- socket.send(packet);
- }
-
- socket.close();
-
- }
- }
接收端:
- package com.lazyGirl.netdemo.netcase1;
-
- import java.io.IOException;
- import java.net.DatagramPacket;
- import java.net.DatagramSocket;
- import java.net.SocketException;
-
- public class ReceiveMessageDemo {
- public static void main(String[] args) throws IOException {
-
-
- DatagramSocket socket = new DatagramSocket(10086);
-
- byte[] buf = new byte[1024];
- DatagramPacket packet = new DatagramPacket(buf, buf.length);
-
- while (true) {
- socket.receive(packet);
- byte[] data = packet.getData();
- int len = packet.getLength();
- int port = packet.getPort();
- String ip = packet.getAddress().getHostAddress();
- String name = packet.getAddress().getHostName();
-
- System.out.println("ip: " + ip + " name: " + name + " port: " + port + " len: " + len + " data: " + new String(data));
- }
-
- }
- }
输出:
客户端:发送一条数据,接收服务端反馈的消息并打印
服务器:接收数据并打印,再给客户端反馈消息
线程池版:
客户端:
- package com.lazyGirl.netdemo.test3;
-
- import java.io.*;
- import java.net.Socket;
-
- public class Client {
- public static void main(String[] args) throws IOException {
-
- Socket socket = new Socket("127.0.0.1",10086);
- BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.txt"));
- BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
- byte[] buf = new byte[1024];
- int len;
- while ((len = bis.read(buf)) != -1) {
- bos.write(buf, 0, len);
- }
- socket.shutdownOutput();
-
- BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
- String str = br.readLine();
- System.out.println(str);
-
- socket.close();
- }
- }
服务端:
- package com.lazyGirl.netdemo.test3;
-
- import java.io.*;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.UUID;
- import java.util.concurrent.*;
-
- public class Server {
- public static void main(String[] args) throws IOException {
-
- ThreadPoolExecutor pool = new ThreadPoolExecutor(
- 3,
- 16,
- 60,
- TimeUnit.SECONDS,
- new ArrayBlockingQueue<>(2),
- Executors.defaultThreadFactory(),
- new ThreadPoolExecutor.AbortPolicy()
- );
-
- ServerSocket serverSocket = new ServerSocket(10086);
- while (true) {
- Socket socket = serverSocket.accept();
- pool.submit(new MyRunnable(socket));
-
- }
- }
- }
- package com.lazyGirl.netdemo.test3;
-
- import java.io.*;
- import java.net.Socket;
- import java.util.UUID;
-
- public class MyRunnable implements Runnable {
-
- Socket socket;
- public MyRunnable(Socket socket) {
- this.socket = socket;
- }
-
- @Override
- public void run() {
- try{
- BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
- String name = UUID.randomUUID().toString().toString().replaceAll("-", "");
- BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(name + ".txt"));
- int len;
- byte[] buf = new byte[1024];
- while ((len = bis.read(buf)) != -1) {
- bos.write(buf, 0, len);
- }
-
- BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
- bw.write("上传成功");
- bw.newLine();
- bw.flush();
- bw.close();
- }catch (IOException e){
- e.printStackTrace();
- }finally {
- if(socket != null){
- try {
- socket.close();
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
- }
- }
- }
输出: