网络编程,网络通信,网络通信三要素,UDP通信,TCP通信,BS架构

1,网络编程

网络编程:可以让设备中的程序与网络上其他设备中的程序进行数据交互(实现网络通信的)

Java提供的网络编程的解决方案在Java.net.*包下

基本的通信架构

基本的通信架构有2种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)

1)CS架构

【1】Client客户端

1,需要程序员开发

2,用户需要安装

【2】Server服务端

1,需要程序员开发实现

2)BS架构

【1】Browser浏览器

1,不需要程序员开发实现

2,用户需要安装浏览器

【2】Server服务端

1,需要程序员开发实现

无论是CS架构,还是BS架构的软件都必须依赖网络编程

2,网络通信

(1)网络通信三要素

1)IP

IP:设备在网络中的地址,是唯一的标志

lP ( lnternet Protocol):全称”互联网协议地址”,是分配给上网设备的唯一标志

IP地址的两种形式:IPv4,IPv6

【1】IPv4

32位

【2】IPv6

128位

IPv6分成8段表示,每段每四位编码成一个十六进制位表示,数之间用冒号(:)分开

【3】IP域名

http://www.*****.com

1,公网IP

公网IP:是可以连接互联网的IP地址;内网IP:也叫局域网IP,只能组织机构内部使用

2,内网IP

192.168.开头的就是常见的局域网地址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用

3,特殊IP地址

127.0.0.1、localhost:代表本机IP,只会寻找当前所在的主机

4,IP常用命令

ipconfig:查看本机IP地址

ping IP地址:检查网络是否连通

【4】InetAddress

代表IP地址

名称 说明
public static InetAddress getLocalHost() 获取本机IP,会以一个inetAddress的对象返回
public static InetAddress getByName(String host) 根据ip地址或者域名,返回一个inetAdress对象
public String getHostName() 获取该ip地址对象对应的主机名
public String getHostAddress() 获取该ip地址对象中的ip地址信息
public boolean isReachable(int timeout) 在指定毫秒内,判断主机与该ip对应的主机是否能连通

2)端口

端口:应用程序在设备中唯一的标识

标记正在计算机设备上运行的应用程序的,被规定为一个16位的二进制,范围是0~65535

【1】周知端口

0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)

【2】注册端口

1024~49151,分配给用户进程或某些应用程序

【3】动态端口

49152到65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配

注意∶我们自己开发的程序一般选择使用注册端口,且一个设备中不能出现两个程序的端口号一样,否则出错

3)协议

协议:连接和数据在网络中传输的规则

网络上通信的设备,事先规定的连接规则,以及传输数据的规则被称为网络通信协议

开放式网络互联标准:OSI网络参考模型

OSI网络参考模型:全球网络互联标准

TCP/IP网络模型:事实上的国际标准

OSI网络参考模型 TCP/IP网络模型 各层应对 面向操作
应用层 应用层 HTTP、FTP、SMTP... 应用程序需要关注的:浏览器,邮箱。程序员一般在这一层开发
表示层
会话层
传输层 传输层 UDP、TCP... 选择使用的TCP , UDP协议
网络层 网络层 IP... 封装源和目标IP
数据链路层 数据链路层+物理 比特流... 物理设备中传输
物理层
【1】UDP协议

UDP(User Datagram Protocol):用户数据报协议

通信效率高

特点:无连接、不可靠通信

不事先建立连接,数据按照包发,一包数据包含:自己的IP、程序端口,目的地IP、程序端口和数据(限制在64KB内)等

发送方不管对方是否在线,数据在中间丢失也不管,如果接收方收到数据也不返回确认,故是不可靠的

【2】TCP协议

TCP(Transmission Control Protocol):传输控制协议

通信效率相对不高,数据可靠

特点:面向连接、可靠通信

TCP的最终目的:要保证在不可靠的信道上实现可靠的传输

TCP主要有三个步骤实现可靠传输:三次握手建立连接,传输数据进行确认,四次挥手断开连接

(2)UDP通信

Java提供了一个java.net.DatagramSocket类来实现UDP通信

DatagramSocket:用于创建客户端、服务端

构造器 说明
public DatagramSocket() 创建客户端的Socket对象。系统会随机分配一个端口号
public DatagramSocket(int port) 创建服务端的Socket对象,并指定端口号
方法 说明
public void send(DatagramPacket dp) 发送数据包
public void receive(DatagramPacket p) 使用数据包接收数据

DatagramPacket:创建数据包

构造器 说明
public DatagramPacket(byte[] buf,int length,InetAddress haddress,int port) 创建发出去的数据包对象
public DatagramPacket(byte[] buf, int length) 创建用来接收数据的数据包

方法 说明
public int getLength() 获取数据包,实际接收到的字节个数
//客户端
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class ddd {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket=new DatagramSocket();

        Scanner sc=new Scanner(System.in);
        //多发
        while (true) {
            System.out.println("请说:");
            String msg=sc.nextLine();

            //退出
            if ("exit".equals(msg)){
                System.out.println("欢迎下次光临~~~");
                socket.close();//关闭资源
                break;
            }
            byte[]bytes=msg.getBytes();
            DatagramPacket packet=new DatagramPacket(bytes,bytes.length,
                    InetAddress.getLocalHost(),6666);

            socket.send(packet);
        }
    }
}
//服务端
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动~~~~");
        DatagramSocket socket=new DatagramSocket(6666);

        //创建一个数据包对象
        byte[]buffer=new byte[1024*64];
        DatagramPacket packet=new DatagramPacket(buffer,buffer.length);

        while (true) {
            socket.receive(packet);

            //接多少,倒多少
            int len= packet.getLength();
            String rs=new String(buffer,0,len);
            System.out.println(rs);
            System.out.println("------------------------");
        }
    }
}

多开操作

网络编程,网络通信,网络通信三要素,UDP通信,TCP通信,BS架构_第1张图片

网络编程,网络通信,网络通信三要素,UDP通信,TCP通信,BS架构_第2张图片

网络编程,网络通信,网络通信三要素,UDP通信,TCP通信,BS架构_第3张图片

(3)TCP通信

Java提供了一个java.net.Socket类来实现TCP通信

1)TCP通信-客户端开发

客户端程序就是通过java.net包下的Socket类来实现的

构造器 说明
public Socket(String host , int port) 根据指定的服务器ip、端口号请求与服务端建立连接,连接通过,就获得了客户端socket
方法 说明
public OutputStream getOutputStream() 获得字节输出流对象
public InputStream getInputStream( ) 获得字节输入流对象

2)TCP通信-服务端开发

服务端是通过java.net包下的ServerSocket类来实现的

构造器 说明
public ServerSocket(int port) 为服务端程序注册端口
方法 说明
public Socket accept() 阻塞等待客户端的连接请求,一旦与某个客户端成功连接,则返回服务端这边的Socket对象
//客户端
import java.io.DataOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;

public class ccc {
    public static void main(String[] args) throws Exception {
        Socket socket=new Socket("192.168.187.133",8888);

        //创建字节输出流
        OutputStream os= socket.getOutputStream();

        //字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);

        Scanner sc=new Scanner(System.in);
        while (true) {
            System.out.println("请说:");
            String msg=sc.nextLine();

            if ("exit".equals(msg)){
                System.out.println("欢迎下次光临~~~");
                dos.close();
                socket.close();
                break;
            }

            dos.writeUTF(msg);
            dos.flush();
        }
    }
}
//服务端
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动~~~");
        ServerSocket serverSocket=new ServerSocket(8888);

        //使用ServerSocket对象等待客户端连接请求
        Socket socket = serverSocket.accept();

        //得到一个字节输入流
        InputStream is= socket.getInputStream();

        //字节输入流包装成数据输入流
        DataInputStream dis=new DataInputStream(is);

        while (true) {
            try {
                //读取客户端的数据
                String rs= dis.readUTF();
                System.out.println(rs);
            } catch (IOException e) {
                System.out.println(socket.getRemoteSocketAddress()+"离线了~~~~");
                dis.close();
                socket.close();
                break;
            }
        }
    }
}

(4)TCP-支持与多个客户端通信

因为服务端现在只有一个主线程,只能处理一个客户端的消息,所以不可以支持与多个客户端同时通信

客户端同UDP操作

//服务端
import java.net.ServerSocket;
import java.net.Socket;

public class Server1 {
    public static void main(String[] args) throws Exception {
        System.out.println("服务端启动~~~");
        ServerSocket serverSocket=new ServerSocket(8888);

        while (true) {
            //使用ServerSocket对象等待客户端连接请求
            Socket socket = serverSocket.accept();

            System.out.println("有人上线了:"+socket.getRemoteSocketAddress());

            //建立独立线程
            new ServerReaderThread(socket).start();
        }
    }
}
//ServerReaderThread
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ServerReaderThread extends Thread{
    public Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run(){
        try {
            InputStream is= socket.getInputStream();
            DataInputStream dis=new DataInputStream(is);
            while (true){
                try {
                    String msg= dis.readUTF();
                    System.out.println(msg);
                } catch (IOException e) {
                    System.out.println("有人下线了:"+socket.getRemoteSocketAddress());
                    dis.close();
                    socket.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

(5)BS架构

BS架构的基本原理:

http://服务器IP:服务器端口

注意:服务器必须给浏览器响应HTTP协议规定的数据格式,否则浏览器不识别返回的数据

HTTP协议规定:响应给浏览器的数据格式必须满足如下格式

网络编程,网络通信,网络通信三要素,UDP通信,TCP通信,BS架构_第4张图片

//ServerReaderRunnable
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;

public class ServerReaderRunnable implements Runnable{
    private Socket socket;
    public  ServerReaderRunnable(Socket socket){
        this.socket=socket;
    }
    @Override
    public void run(){
        try {
            OutputStream os= socket.getOutputStream();
            PrintStream ps=new PrintStream(os);
            ps.println("HTTP/1.1 200 OK");
            ps.println("Content-Type:text/html;charset=UTF-8");
            ps.println();//换行
            ps.println("
猜猜我是谁?
"); ps.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } } }
//服务端
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Server {
    public static void main(String[] args) throws Exception{
        System.out.println("服务端启动~~~");
        ServerSocket serverSocket=new ServerSocket(8888);

        ThreadPoolExecutor pool = new ThreadPoolExecutor(16 * 2, 16 * 2, 0, TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(8), Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        while (true) {
            //使用ServerSocket对象等待客户端连接请求
            Socket socket = serverSocket.accept();

            pool.execute(new ServerReaderRunnable(socket));
        }
    }
}

你可能感兴趣的:(网络,java)