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

本文详细介绍了Java网络编程,包括CS架构(客户端-服务器)和BS架构(浏览器-服务器)的基本原理,涉及IP地址、端口、TCP和UDP协议的应用,以及如何在Java中使用Socket和ServerSocket进行TCP通信,以及HTTP协议在BS架构中的应用。
摘要由CSDN通过智能技术生成

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("------------------------");
        }
    }
}

多开操作

(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协议规定:响应给浏览器的数据格式必须满足如下格式

//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("<div style='color:red;font-size:120px;text-align:center'>猜猜我是谁?<div>");
            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));
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值