java网络编程

1、什么叫计算机网络?

  由不同地理位置的不同计算机主机,连接起来组成的网络。

2、什么叫网络编程?

  在网络的基础上,使用网络进行编程,对应用层进行设计的活动。

3、网络编程三要素:IP地址、端口、通讯协议

IP地址

1、在计算机网络中某个计算机的唯一标识

2、在计算机网络中,现在命名IP地址的规定是IPv4协议,该协议规定每个IP地址由4个0-255之间的数字组成(也就是32位),一共有2^32个,超过40亿。IP地址是一个32位的二进制数,通常被分割为4个“8位二进制数”(也就是4个字节)。IP地址通常用“点分十进制”表示成(a.b.c.d)的形式,其中,a,b,c,d都是0~255之间的十进制整数。

3、由于IP地址不好记忆,所以有了域名,一个域名对应一个ip,但一个IP可以对应很多域名。类似于一个人可以有很多微信,但一个微信只对应一个人。

4、IPv6是下一版本的互联网协议,也可以说是下一代互联网的协议,它的提出最初是因为随着互联网的迅速发展,IPv4定义的有限地址空间将被耗尽,而地址空间的不足必将妨碍互联网的进一步发展。为了扩大地址空间,拟通过IPv6以重新定义地址空间。IPv4采用32位地址长度,只有大约43亿个地址,而IPv6采用128位地址长度,几乎可以不受限制地提供地址。

5、IP地址编址方式:A、B、C、D、E五类地址

(1)A类地址是指:IP地址的四段地址中只有第一段为网络号码,其余三段为计算机本地号码。

  A类IP地址 地址范围1.0.0.1到127.255.255.254

  二进制表示为:00000001 00000000 00000000 00000001 - 01111111 11111111 11111111 11111110。最后一个是广播地址。(最高位必须是0),子网掩码:255.0.0.0

(2)B类地址是指:在IP地址的四段号码中,前两段号码为网络号码。

  B类IP地址地址范围128.0.0.1-191.255.255.254

  二进制表示为:10000000 00000000 00000000 00000001----10111111 11111111 11111111 11111110。 最后一个是广播地址。(最高位必须是10),B类IP地址的子网掩码为255.255.0.0。

(3)C类地址是指:在IP地址的四段号码中,前三段号码为网络号码,剩下的一段号码为本地计算机的号码。

  C类IP地址范围192.0.0.1-223.255.255.254

  二进制表示为: 11000000 00000000 00000000 00000001 - 11011111 11111111 11111111 11111110。(最高位必须是110)

C类IP地址的子网掩码为255.255.255.0

(4)D类IP地址在历史上被叫做多播地址(multicast address),即组播地址。

  多播地址的最高位必须是“1110”,范围从224.0.0.0到239.255.255.255。

(5)IP地址中凡是以“11110”开头的E类IP地址都保留用于将来和实验使用

(6)特殊IP:

  0.0.0.0 对应当前主机

  255.255.255.255对应当前子网的广播地址

  127.0.0.1到127.255.255.255用于回路测试,127.0.0.1对应本机IP地址

端口

1、是一个数字,用来标记电脑里的某个进程。

2、使用两个字节表示端口,0-65535,意味着计算机中同时运行的进程最多有65536个

  当一个程序运行时,需要一个端口号,运行结束后,端口号被收回

3、作用:一个计算机上可以并发运行多个网络程序,而不会在互相之间产生干扰。一个进程在网络中进行通讯时,先通过IP地址找到电脑,然后通过端口找到对应进程。

4、程序运行时可以指定端口号,也可以随机分配。0-1024是系统需要的端口号

通讯协议

1、通讯双方在信息交互时,对信息的封装和解析的规则,就称为协议

2、讯协议又称通信规程,是指通信双方对数据传送控制的一种约定。约定中包括对数据格式,同步方式,传送速度,传送步骤,检纠错方式以及控制字符定义等问题做出统一规定,通信双方必须共同遵守,它也叫做链路控制规程。

3、应用层:http协议、https协议、FTP协议

  传输层:UDP协议、TCP协议

  网络层:IP协议

  物理层:底层硬件设备、数据的完整和校验

网络的几种结构

1、客户端/服务器结构,也叫做Client/Server结构,简称C/S结构(需要三次握手)

2、浏览器/服务器结构,也叫做Browser/Server结构,简称为B/S结构

3、P2P结构

java中的网络编程技术

1、java 为我们提供了一个InetAddress类,该类的功能是代表一个IP地址,并且将IP地址和域名相关的操作方法包含在该类的内部。

2、获取方式:

  getByName(String host):根据主机名称获取当前类型对象

  getByAddress(byte[] arr):根据ip地址的字节数组获取当前类型对象

  getAllByName(String host):根据主机名称获取的所有当前类型对象的数组

  getLocalHost():获取当前主机的当前类型对象

3、对象的常用方法:

  getHostName():获取主机名称

  getAddress():获取ip地址的字节数组

  toString():同时获取主机名称和ip地址的字符串表示

4、代码示例

import java.net.InetAddress;
import java.util.Arrays;

public class Test1 {

    public static void main(String[] args) throws Exception {
        //获取主机名称的IP地址
        InetAddress ip1 = InetAddress.getByName("www.baidu.com");
        System.out.println(ip1);
         String s1 =ip1.getHostName();//获取主机名
         byte[] b1 = ip1.getAddress();//获取原始地址
        System.out.println(s1+"..."+Arrays.toString(b1));
        System.out.println("---------------------------------");
        
        //根据ip地址的字节数组获取当前类型对象
        byte[] b2 = {61,-121,-87,125};
        InetAddress ip2 = InetAddress.getByAddress(b2);
        System.out.println(ip2);
        System.out.println("---------------------------------");

        //根据本地回环地址获取当前类型对象
        byte[] b3 = {127, 0, 0, 1};
        InetAddress ip3 = InetAddress.getByAddress(b3);
        System.out.println(ip3);
        System.out.println(ip3.getHostName() + "..." + Arrays.toString(ip3.getAddress()));
        System.out.println("---------------------------------");
        
        //获取本机当前类型对象
        InetAddress ip4 = InetAddress.getLocalHost();
        System.out.println(ip4);
        System.out.println(ip4.getHostName() + "..." + Arrays.toString(ip4.getAddress()));
    }

}

UDP协议和TCP协议

1、都是传输层协议,端到端协议。

2、区别:

  UDP协议面向无连接,像发短信,寄信,先发送的消息未必先到达,不安全,效率高,只区分发送端和接收端,而不区分客户端和服务端

  TCP协议面向连接,像打电话,先发送的消息一定是先到,安全,效率低,区分客户端和服务端。在连接的时候,会有三次握手的动作。

3、Socket  两台计算机的通讯点,类似于码头、邮局。。。

  Socket:也称为套接字,套接字编程:网络编程、通信点编程(端到端编程)

  不同的协议中,使用的Socket对象各不相同:UDP协议中,使用的是DatagramSocket;在TCP协议中,客户端使用的是Socket、服务端使用的ServerSocket和Socket

UDP的编程实现

1、使用的Socket是DatagramSocket

2、构造方法

  DatagramSocket():不指定端口号,创建通信点,端口号随机分配,一般用于发送端

  DatagramSocket(int port):指定端口号,创建通信点,一般用于接收端

3、成员方法

  send(DatagramPacket dp):将一个dp数据报包发送

  receive(DatagramPacket dp):将数据接收到dp参数中

4、DatagramPacket介绍:

  1、表示一个数据报数据的封装对象的类型

  2、构造方法:  

      DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port) 

        buf:要发送的数据的字节数组

        offset:从数组的哪个位置开始发送

        length:发送多少数据

        address:发送到哪个ip

        port:发送到哪个程序

  3、常用成员方法:

        getData():返回该数据包中的字节数组

        getLength():返回该数据包中接收到的字节个数

5、UDP编程步骤

  发送端:

    1、准备通讯点对象

    2、准备要发送的包裹对象

    3、调用通讯点的发送方法

  接受端:

    1、准备通讯点对象

    2、准备接收端的接收容器

    3、调用接收方法 

    4、解析收到的数据

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;

public class Send {

    public static void main(String[] args) throws Exception {
        String host = "127.0.0.1";
        //创建发送端
        DatagramSocket ds = new DatagramSocket();
        //要发送的数据
        Scanner sc = new Scanner(System.in);
        while(true) {//循环发送时要注意socket两边步骤要保持一致
            System.out.println("要发送的内容:");
            byte[] buf =sc.nextLine().getBytes();
            //目标地
            InetAddress address = InetAddress.getByName(host);
            //创建包
            DatagramPacket dp = new DatagramPacket(buf, 0, buf.length,address, 9999);
            ds.send(dp);
            System.out.println("是否继续?1是,0否");
            if("1".equals(sc.nextLine())) {
                continue;
            }else break;
        }
        sc.close();
        ds.close();//注意关闭资源
    }

}
发送端
import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Receive {

    public static void main(String[] args) throws Exception {
        DatagramSocket ds = new DatagramSocket(9999);//接收端要指定端口号
        while(true) {
            byte[] buf = new byte[1024];
            //创建接收容器
            DatagramPacket dp = new DatagramPacket(buf, buf.length);
            ds.receive(dp);//调用接收方法
            byte[] data = dp.getData();
            int len = dp.getLength();
            System.out.println(new String(data,0,len));//解析内容
        }
    }
}
接收端

TCP的编程实现

1、使用的通讯点就是Socket类型

2、客户端和服务端获取Socket对象的区别:

  1、客户端使用Socket的构造方法,创建一个Socket对象

  2、服务端不能使用自己创建的方式,而是使用服务端一个特殊的对象ServerSocket,接收客户端发来的请求,生成一个为这个客户端服务的Socket对象

3、构造方法:

  Socket(InetAddress ip, int port):建立一个通信点,专门用于和ip主机的port程序进行通信。

  只要这个对象创建成功了,就说明这个连接已经建立起来了,就说明当前的客户端已经联系上服务端了,已经获取了服务端返回的响应。

  在创建对象的过程,就是在请求和服务端连接的过程。

4、服务端获取Socket对象的方式:

  1、启动一个服务程序,类型是ServerSocket,可以接收客户端发来的连接请求,一旦接收到请求,就可以创建一个和当前客户端交互的Socket对象

  2、ServerSocket的构造方法

      ServerSocket(int port):创建一个服务端Socket对象,等待访问port端口的客户端(监听此端口)

  3、accept():接收一个客户端发来的请求,返回一个服务此客户端的Socket对象

5、获取客户端和服务端的连接

  1、两个方法:

      InputStream  getInputStream():获取Socket对象的网络输入流

      OutputStream  getOutputStream():获取Socket对象的网络输出流

  2、一旦获取了输入输出流,就可以通过I\O的方式,来操作网络数据的传输。

  3、对应关系:

      客户端的网络输入流,对应服务端的网络输出流

      客户端的网络输出流,对应服务端的网络输入流

6、TCP编程步骤

  客户端:

    1、创建Socket对象,建立和服务端的连接

    2、获取网络输入流和输出流

    3、通过I/O的操作进行数据的传输

  服务器端:

    1、创建ServerSocket对象,开启服务器,监听端口

    2、调用accept方法,接收客户端请求,返回Socket对象

    3、获取网络输入流和输出流

    4、通过I/O的操作进行数据的传输

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;

public class TCPClient {

    public static void main(String[] args) throws Exception {        
        //String s = "10.10.92.184";
        InetAddress s = InetAddress.getLocalHost();
        int port = 9999;        
        while(true) {//注意,客户端和服务器端要保证流程一致
            //创建客户端通讯点
            Socket socket = new Socket(s,port);
            OutputStream os = socket.getOutputStream();
            //使用打印流进行包装
            PrintStream ps = new PrintStream(os);
            //获得网络输入流
            Scanner sc = new Scanner(System.in);
            ps.println(sc.nextLine());
            //获得网络输出流
            InputStream is = socket.getInputStream();
            //使用转换流进行包装
            InputStreamReader isr = new InputStreamReader(is);
            //使用高效缓冲流进行包装
            BufferedReader br = new BufferedReader(isr);
            System.out.println(br.readLine());    
        }
    }
}
加强版客户端
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Server {

    public static void main(String[] args) throws Exception {
        // 创建服务器端ServerSocket对象,监听9999端口,接受客户端的请求
        ServerSocket ss = new ServerSocket(9999);
        //创建线程池,避免浪费资源
        ExecutorService es = Executors.newFixedThreadPool(10);
        while(true) {
            // 接受客户端的请求
            Socket s = ss.accept();//阻塞式方法
            //使用匿名内部类方法创建多线程,使服务器可以和多个客户端通讯
             Runnable r = new Runnable() {
                public void run() {
                    try {
                        //获得输入流
                        InputStream is = s.getInputStream();
                        //转换流包装
                        InputStreamReader isr = new InputStreamReader(is);
                        //高效缓冲流包装
                        BufferedReader br = new BufferedReader(isr);
                        System.out.println(s.getLocalAddress()+"..."+s.getPort()+"..."+br.readLine());
                        
                        //获得输出流
                        OutputStream os = s.getOutputStream();
                        //打印流包装
                        PrintStream ps = new PrintStream(os);
                        ps.println("收到");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            es.submit(r);//加入线程池
        }
    }
}
加强版服务器

7、TCP编程加强

  1、让客户端也接收数据,服务端也发送数据

  2、让字节流进行加强,转成字符流,加强成缓冲字符流

  3、让服务端多线程,同时可以处理多个用户的请求

 

 

 

posted on 2019-07-27 21:17  幸福的小耗子  阅读(249)  评论(0编辑  收藏  举报