计算机网络与Java网络编程基础知识总结

关于Java网络编程

计算机网络将地理位置不同的计算机通过通信线路连接起来,实现资源的共享和信息的传递,网络中的计算机通常称之为主机,而网络编程就是通过程序来实现两台以上主机之间的通信。
实际的通信网络内容较多,但是Java语言提供了许多网络类,屏蔽了底层的复杂细节,是程序员可以很容易地编写出网络程序。

计算机网络知识基础

在进行Java网络编程之前,需要对关于计算机网络的总体知识有一个大致的理解。

分层结构模型

众所周知,计算机网络传输实际上是一个很复杂的模型,为了更方便程序开发,我们一般会简历网络传输模型,将各个不同的层次分隔开,由不同的人来设计不同的层次,这样设计各个层次的人就不用管其他层面的具体实现,每一层都呼叫它的下一层所提供的网络来完成自己的需求,只需要调用别人的服务就可以了,大大提高了工作效率。除此之外,因为各层之间是独立的,结构上可分割开,所以灵活性好,易于实现和维护,能促进标准化工作:差错控制,流量控制,分段和重装,复用和分用,连接建立和释放。

常见的模型由三种:

1.OSI七层体系

在这里插入图片描述

2.五层体系

5层只是OSI和TCP/IP的综合,是业界产生出来的非官方协议模型,但是很多具体的应用。实际应用还是TCP/IP的四层结构。
在这里插入图片描述

3.TCP/IP四层体系

在这里插入图片描述
该体系将数据链路层和物理层合并为网络接口层。

总结

OSI总结图
本图来自于https://blog.csdn.net/cc1949/article/details/79063439
TCP/IP协议与其的关系()
本图来自于https://blog.csdn.net/cc1949/article/details/79063439
这是其中有关于协议的数据报文格式:
在这里插入图片描述

Java网络编程基础

计算机在网络通信协议中必须遵守一定的规则,就好比车辆行驶要遵守交通规则一样,在计算机网络协议中,这些连接和通信的规则被称为网络通信协议,它对传输格式,传输速率,传输步骤做了统一的规定,通信双方必须遵守这些协议才能进行数据交换;

网络通信协议有很多种,但是目前主要使用的还是TCP/IP、UDP、ICMP和一些其他协议;

IP地址与端口号

要想使计算机能够通信,必须要为每台计算机指定标识号,通过标识号来指定接收或发送数据的计算机,在TCP/IP协议中,这个标识号就是IP地址,目前普遍使用的是4个字节的IPV4,不过为了解决日渐枯竭的网络地址资源不足,现在16个字节IPV6也应运而生;

IP地址一般由两部分组成,是 网络号+主机号,网络号指定网络地址,主机号指定该网络中的主机地址,二者是主从关系;

通过IP地址可以连接到指定计算机,但是如果想要访问计算机中某个应用程序,还需要指定端口号,在计算机中,不同的应用程序是通过端口号来区分的,端口号是用两个字节(16位的二进制数)来表示的,取值范围为0到65533,但其中0到1023的端口号被系统的网络服务所占有,所以用户的普通应用的端口号不能属于这个范围;

总得来说,一台计算机可以通过IP地址来访问到网络中的另一台计算机,并通过端口号来访问这个计算机中的某个应用程序;

InetAddress类

这是Java中提供的与IP地址相关的InetAddress类,该类用于封装IP地址,并提供了一系列与IP地址相关的方法,该类的方法有以下几个,例如:

InetAddress  getByName(String host)    得到IP地址封装为InetAddress类

InetAddress getLocalHost()          创建一个表示本地主机的InetAddress对象

String getHostName()               得到字符串格式的原始IP地址

String getHostHome()             得到确定的IP地址的主机名

boolean isReachable(int timeout)        判断在指定的时间内地址是否可以到达

TCP和UDP

TCP和UDP是两个传输层的高级协议;

UDP是用户数据报协议,TCP是传输控制协议;

UDP是无连接通信协议,在数据传输的时候,数据的发送端和接收端并不建立逻辑连接,简单来说,当一台计算机向另外一台计算机发送数据时,并不好确认接收端是否存在,就直接发送数据,接收端在接受数据的时候,也不会向发送端反馈是否收到数据。
由于UDP消耗资源小,传输效率高,,所以通常用于音视频和普通数据的传输,比如说直播视频,但是由于UDP的无连接性,不能保证数据传输的完整性,所以在传输重要数据的时候不建议使用UDP。

TCP是面向连接的通信协议,即在传输数据的时候先在发送端和接收端建立逻辑连接,然后再传输数据;这提供了两台计算机之间可靠的,无差错的数据传输;
由于TCP的面向连接的特性,它可以保证数据传输的安全性,所以是一个被广泛采取的协议,比如在下载压缩包文件的时候,就非常适合使用TCP连接。

在TCP连接过程中,必须要明确客户端和服务器端,由客户端来向服务器端发出连接请求;
每次连接都需要经历三次握手协议;
三次握手协议:
第一次握手,客户端向服务器端发出连接请求,等待服务器端的确认;
第二次握手,服务器端向客户端回复一个响应,通知客户端收到了连接请求;
第三次握手,客户端向服务器端发送确认信息,确认连接;

而在TCP断开链接的时候,就需要用到四次挥手协议
第一次挥手,若A认为数据发送完成,则它需要向B发送连接释放请求。
第二次挥手,B收到连接释放请求后,会通知相应的应用程序,告诉它A向B这个方向的连接已经释放。
第三次挥手,当B向A发完所有数据后,向A发送连接释放请求
第四次挥手,A收到释放请求后,向B发送确认应答。

TCP协议作为一个可靠的面向流的传输协议,其可靠性和流量控制由滑动窗口协议保证,而拥塞控制则由控制窗口结合一系列的控制算法实现,以及快重传和快恢复,超时重传来确保文件完整性。

两者所在层次:
在这里插入图片描述
两者特点比较:
在这里插入图片描述

TCP网络编程

ServerSocket

用于建立TCP连接,该类可以实现一个服务端的程序;

1、构造ServerSocket

ServerSocket()throws IOException  //ServerSocket有一个不带参数的默认构造方法。通过该方法创建的ServerSocket不与任何端口绑定,接下来还需要通过bind()方法与特定端口绑定,这个默认构造方法的用途是,允许服务器在绑定到特定端口之前,先设置ServerSocket的一些选项。因为一旦服务器与特定端口绑定,有些选项就不能再改变了。

ServerSocket(int port) throws IOException   //使服务器与特定端口绑定,该端口由参数port指定

ServerSocket(int port, int backlog) throws IOException  //参数backlog指定客户连接请求队列的长度

ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException  //参数bindAddr指定服务器要绑定的IP地址

2.使用ServerSocket进行服务端编程

import java.io.*;
import java.net.*;
import java.util.*;

public class qwe {
    public static void main(String[] args) {
        ServerSocket server = null;  //创建服务器Socket对象
        Socket socket = null;  //创建Socket对象,用于接收另一端socket的连接

        DataInputStream in = null;
        DataOutputStream out = null;  //准备好IO流

        int port = 5050;//设置端口号

        try{
            server = new ServerSocket(port);
        }
        catch (IOException e){
            System.out.println(e);
        }//创建ServerSocket对象,绑定5050端口

        try{
            System.out.println("服务器启动");
            socket = server.accept();//准备监听Socket连接并接收

            in = new DataInputStream(socket.getInputStream());//返回一个输入流对象
            out = new DataOutputStream(socket.getOutputStream());//返回一个输出流对象

            //socket之间是通过IO流来交互信息的

            String str = in.readUTF();
            System.out.println("收到信息为:"+str);
            out.writeUTF("你好");
            
        }catch(Exception e){
            System.out.println(e);
        }
        
        finally {
        //准备关闭连接
            try{
                out.close();
                in.close();
                socket.close();//Socket对象的关闭连接方法
                server.close();
            }catch (Exception e){
                System.out.println(e);
            }
        }
        
    }
}
      

Socket(客户端)

import java.io.*;
import java.net.*;

public class qwe {
    public static void main(String[] args){
        Socket client = null;
        DataInputStream in = null;
        DataOutputStream out = null;
        
        String ip = "127.0.0.1";
        int port = 5050;
        
        try
        {
            client = new Socket(ip,port);//客户端socket绑定端口和ip地址
            
            in = new DataInputStream(client.getInputStream());
            out = new DataOutputStream(client.getOutputStream());
            
            out.writeUTF("这里是客户端");
            String str = ((DataInputStream) in).readUTF();
            System.out.println(str);
        }catch (Exception e){
            System.out.println(e);
        }finally {
            try{
                in.close();
                out.close();
                client.close();
            }catch (Exception e){
                System.out.println(e);
            }
        }
    }
}

UDP网络编程

UDP是一种无连接的不可靠传输协议,在使用UDP进行网络连接通信的时候,不需要建立连接,所以速度块,发送的时候需要封装成数据包,就像把信件装入信封。

DatagramPacket

UDP通信过程中并不建立连接,就像是两个货运公司在两个码头之间运送货物一样,在码头发送和接受货物都需要使用集装箱来装载货物。UDP通信也是一样,我们需要使用DatagramPacket类,该类的实例对象就相当与一个集装箱,也可以说是一个信封,我们就利用这个东西对我们需要发送的文件进行打包发送,总之,这个类是用来发送的。

构造方法:

DatagramPacket(byte[] data, int length)  //指定了封装信息的字节数组大小,以及数组的长苏

DatagramPacket(byte[] data, int offset, int length)  //在上面的基础上,增加了offset,用于指定数据的缓冲位置

DatagramPacket(byte[ ] data, int length, InetAddress  address, int port)  //增加了指定的目标IP地址address和目的端口号port

DatagramPacket(byte[] data, int offset, int length,  InetAddress address, int port) //完整版

常用方法:
InetAddress getAddress()    //返回IP地址

int getPort()  //返回端口号

byte[] getData()    //返回打包的数据

int getLength()  //返回数据字节数组的长度

DatagramSocket

如果说DatagramPacket相当于一个集装箱,然而,两个货运公司之间的传输仅仅使用集装箱是不够的,我们还需要一个码头进行接收集装箱,在Java中,我们使用DatagramSocket来当作“码头”,使用该类的实例对象就可以接收或发送DatagramPacket数据包,总之,这个类是用来接收的。

构造方法:

DatagramSocket()   //用于创建一个DatagramSocket对象,如果没有给端口号,系统会从其他应用自动分配一个

DatagramSocket(int port)   //指定了端口号,这样对象可以监听指定的端口

DatagramSocket(int port,InetAddress addr)   //指定了端口号和IP地址,该对象适用与计算机上有多块网卡的情况,因为计算机针对不同的网卡会分配不同的IP地址,所以指定IP地址就可以确定你到底要使用哪块网卡来通信

void  receive(DatagramPacket p) //接收包

void send(DatagramPacket p)  //发送包

void close //关闭

UDP编程实例

import java.io.*;
import java.net.*;

public class qwe {
    public static void main(String[] args) {
        DatagramSocket socket = null;//码头,利用其的send和receive方法来进行发送和接收
        DatagramPacket packet_send = null;//集装箱,用于发送
        DatagramPacket packet_receive = null;//集装箱,用于接收

        int port = 5050;
        String ipAddress = "127.0.0.1";

        try{
            socket = new DatagramSocket(port);//建立好连接

            byte[] r = bew byte[1024];
            packet_receive = new DatagramPacket(r,r.length);
            socket.receive(packet_receive);//接受从另一端发送过来的数据

            InetAddress address = InetAddress.getByName(ipAddress);//封装好InetAddress
            String str = "服务端发送数据";
            byte[] r = str.getBytes();//开始打包
            packet_send = new DatagramPacket(r,r.length,address,port);//打包好数据

            socket.send(packet_send);//将数据包发送到另一端
        }
        catch (Exception e)
        {
            System.out.println(e);
        }
        finally {
            socket.close();//关闭连接
        }

    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值