JavaSE——网络编程

网络

网络编程

计算机网络

概念:计算机网络是将不同的地理区域的具有独立功能的计算机,通过通信线路连接起来,由功能完善的软件实现资源共享和信息传递的系统。

网络编程概述

概念:通过计算机语言设计软件,使用软件在网络上进行数据的交换

目的:直接或间接地通过网络协议与其他计算机进行通讯

网络编程中有两个主要的问题:

如何准确地定位网络上一台或多台主机 ​ 找到主机后如何可靠高效地进行数据传输

java中的网络编程

java在语言级上提供了提供了对网络应用程序的支持,使得java程序员能够很容易开发常见的网络应用程序,java在ava提供的网络类库,可以实现网络连接,联网的底层细节被隐藏在Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境。

Java将支持网络编程的类都封装在了java.net包下,提供了支持TCP/UDP传输的实现类

网络模型

 

OSI模型 分为七层,是理想参考模型

TCP/IP模型 分为四层,是实际实现的模型

网络的通信要素

IP地址

IP地址(Internet Protocol Address)是指互联网协议地址,又译为网际协议地址.网络中的计算机使用IP地址来进行唯一标识

在Windows系统下,打开cmd,输入命令ipconfig,按回车即可查看。

其中本地回环地址(hostAddress):127.0.0.1 ,它代表设备的本地虚拟接口.

端口号

端口号是计算机程序中的一个整数数字标号,用来区分不同的应用程序

0 ~ 1024 未被系统使用或保留的端口号,0 ~ 65535为有效的端口号,也就是说我们要对一些程序定义端口号的时候,要选择1024 ~ 65535范围内的整数数字。常见的端口号有例如MySql:3306,SQLServer:1433, Oracle:1521,使用IP地址与端口号就可以定位网络上某一台主机上的某个程序

协议

网络通信协议:计算机网络中实现通信必须有一些约定,即通信协议,对速率、传输代码、代码结构、 传输控制步骤、出错控制等制定标准。

在学习java的过程中必须要了解传输层(运输层)的两个协议:传输控制协议TCP(Transmission Control Protocol)与用户数据报协议UDP(User Datagram Protocol)

TCP协议

使用协议前必须采用”三次握手“的方式去建立连接,形成传输数据通道,是安全可靠的

TCP协议进行通信的两个应用进程:客户端、服务端

在连接中可进行大数据量的传输

传输完毕,需释放已建立的连接,效率低

在断开时要进行“四次挥手”

 

 

UDP协议

将数据,源(ip地址),目的封装成数据包(报),无需要建立连接

每个数据报的大小限制在64K内

因无需连接,故是不可靠的

发送数据结束时无需释放资源,速度快

TCP编程

利用套接字(Socket)开发网络应用程序早已被广泛的采用,以至于成为事实上的标准

        ● 通信的两端即客户端与服务器端都要有Socket,是两台机器间通信的端点

        ● 网络通信其实就是Socket间的通信

        ● Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输

客户端Socket的工作过程:

        ● 创建 Socket:根据指定服务端的 IP 地址或端口号构造 Socket 类对象。若服务 器端响应,则建立客户端到服务器的通信线路。若连接失败,会出现异常。

        ● 打开连接到 Socket 的输入/出流: 使用 getInputStream()方法获得输入流, 使用 getOutputStream()方法获得输出流,进行数据传输

        ● 按照一定的协议对 Socket 进行读/写操作:通过输入流读取服务器放入线路的 信息(但不能读取自己放入线路的信息),通过输出流将信息写入线程。

        ● 关闭 Socket:断开客户端到服务器的连接,释放线路

Socket类的构造方法:

Socket(String host,int port)throwsUnknownHostException,IOException:

向服务器(域名是host。端口号为port)发起TCP连接,若成功,则创建Socket对象,否则抛出异常。 Socket(InetAddress address,int port)throws IOException:

根据InetAddress对象所表示的IP地址以及端口号port发起连接。

通信套接字Socket类对象在客户端创建的时候会自动向服务器方发起连接

public class Client {
    public static void main(String[] args) throws IOException {//为方便测试在main方法中抛出异常,下面测试做法相同
        Socket socket=new Socket("127.0.0.1",9999);//在创建Socket类对象的时候会自动连接服务器端,检查服务器端是否开启
        //如果服务器端未启动则会抛出异常 java.net.ConnectException: Connection refused: connect
​
        OutputStream out= socket.getOutputStream();//通过socket对象获取一个输出流SocketOutputStream类的对象
        out.write("你好服务器端".getBytes("utf-8"));
​
    }
}

服务器端的工作过程:

        ● 调用 ServerSocket(int port) :创建一个服务器端套接字,并绑定到指定端 ​ 口上。用于监听客户端的请求。 ​

        ● 调用 accept():监听连接请求,进入阻塞状态,如果客户端请求连接,则接受连接,返回通信 ​ 套接字(Socket)对象。 ​

        ● 调用 该Socket类对象的 getOutputStream() 和 getInputStream ():获取 ​ 输出流和输入流,开始网络数据的发送和接收。 ​

        ● 关闭ServerSocket和Socket对象:客户端访问结束,关闭通信套接字。

public class Server {
    public static void main(String[] args) throws IOException {
        try {
            ServerSocket ss = new ServerSocket(9999);//构造方法会抛出异常,防止端口号出现不正常的情况
            //java.net.BindException: Address already in use: JVM_Bind,端口号已被占用的异常
            System.out.println("服务器连接中,请稍后");
​
            //建立客户端监听
            Socket socket = ss.accept();//监听客户端连接,该监听是阻塞式的,没有客户端连接代码就不会继续执行
            System.out.println("客户端连接成功");
            InputStream in = socket.getInputStream();//通过接收到的客户端对象获取一个输入流ScoketInputStream类的对象
​
            byte[] b = new byte[50];
            int size = in.read(b);
​
            String s = new String(b, 0, size, "utf-8");//通过String类的构造方法将接收到的byte数组转换为字符串
            System.out.println("客户端说:" + s);
​
        }catch(BindException bindException){
            bindException.printStackTrace();
            System.out.println("端口号被占用");
​
        }
        ss.close();
        socket.close();//关闭通信套接字
​
    }
}

使用Socket对象的流时可以引入DataOutputStream类与DataInputStream类,这是两个处理流,这两个流可以帮助我们将字符串与字节相互转换,其中的writeUTF(),readUTF()方法可以直接读取字符串,省去了手动转换的流程

        DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(info);
​
        DataInputStream dis=new DataInputStream(socket.getInputStream());
        String serverInfo = dis.readUTF();

若是使用Socket对象传输文件,则在文件传输完成的时候需要使用shutdownOutput()方法告诉服务器端,文件传输完成了

UDP编程

返送端接收端的工作流程:

  1. 在两端都要创建DatagramSocket类与DatagramPacket类对象

  2. 建立数据报对象,将传输的数据,数据长度,IP地址,端口号封装成数据报对象

  3. 调用DatagramSocket的方法send()发送数据报对象、receive()进入阻塞状态接收数据报对象后才继续执行

  4. 关闭Socket对象

发送端代码演示:

public class Send {
    public static void main(String[] args) throws IOException {
        //UDP协议中发送端的任务只有发送数据报,发送成功与否发送端是无法得知的
        //创建套接字对象
        DatagramSocket datagramSocket=new DatagramSocket();
​
        byte [] b="你好接收端".getBytes();
        //建立数据报
        DatagramPacket datagramPacket=new DatagramPacket(b,0,b.length,InetAddress.getByName("127.0.0.1"),9999);
​
        //发送数据报
        datagramSocket.send(datagramPacket);//调用send方法将数据报发出
​
        datagramSocket.close();//关闭套接字对象
​
    }
}

接收端代码演示:

public class Receive {
    public static void main(String[] args) throws IOException {
        //创建套接字对象
        DatagramSocket datagramSocket=new DatagramSocket(9999);//创建DatagramSocket类对象,指定监听的端口号
​
        byte[] b=new byte[1024];//创建接收的数组
        DatagramPacket datagramPacket=new DatagramPacket(b,b.length);
​
        //接收发送端发送的数据报
        datagramSocket.receive(datagramPacket);//进入阻塞状态,知道接收到数据报之后再执行后面的代码
        String info=new String(datagramPacket.getData(),0,datagramPacket.getLength());
        System.out.println(info);
​
        datagramSocket.close();//关闭套接字对象
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值