JavaSE之网络编程

网络编程

概述

​ Java提供的网络类库,可以实现无痛的网络连接,联网的底层细节被隐藏在 Java 的本机安装系统里,由 JVM 进行控制。并且 Java 实现了一个跨平台的网络库,程序员面对的是一个统一的网络编程环境

目的

直接或间接地通过网络协议与其它计算机实现数据交换,进行通讯。

问题

  1. 如何准确地定位网络上一台或多台主机;定位主机上的特定的**应用 **

  2. 找到主机后如何可靠高效地进行数据传输

网络通信要素

IP和端口号

IP的理解
  1. IP:唯一的标识Internet上的计算机(通信实体)
  2. 在java中使用InetAddress类代表IP
  3. IP分类:IPV4和IPV4 ; 万维网 和 局域网
  4. 域名: www.baidu.com www.mi.com www.sina.com www.jd.com
    •       域名解析:域名容易记忆,当在连接网络时输入一个主机的域名后,域名服务器(DNS)负责将域名转化成IP地址,这样才能和主机建立连接。 -------域名解析
      
  5. 本地回路地址:127.0.0.1对应着localhost
InetAddress类

​ 此类的一个对象就代表着一个具体的IP地址

实例化

​ getByName(String host)、getLocalHost()

常用方法

​ getHostName() / getHostAddress()

端口号

​ 代表正在计算机上运行的进程

要求:不同的进程有不同的端口号

范围:被规定为一个16位的整数0~65535

Socket:由端口号与IP地址的组合得出一个网络套接字

网络通信协议

​ OSI参考模型:模型过于理想化,未能在因特网上进行广泛推广

​ TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。

在这里插入图片描述

TCP和UDP的区别

在这里插入图片描述

TCP三次握手和四次挥手

在这里插入图片描述
在这里插入图片描述

TCP示例
//客户端发送信息给服务端,服务端将数据显示在控制台上
//客户端
    @Test
    public void client()  {
        Socket socket = null;
        OutputStream os = null;
        try {
            //1.创建Socket对象,指明服务器端的ip和端口号
            InetAddress inet = InetAddress.getByName("192.168.14.100");//InetAddress的实例化
            //获取的是服务器端的IP地址
            socket = new Socket(inet,8899);
            //2.获取一个输出流,用于输出数据
            os = socket.getOutputStream();//输出getOutputStream
            //3.写出数据的操作
            os.write("你好,我是客户端mm".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //4.资源的关闭
            if(os != null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
//服务端
 @Test
    public void server()  {

        ServerSocket ss = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        //字节数组输出流在内存中创建一个字节数组缓冲区,所有发送到输出流的数据保存在该字节数组缓冲区中。创建字节数组输出流对象有以下几种方式。
        try {
            //1.创建服务器端的ServerSocket,指明自己的端口号
            ss = new ServerSocket(8899);//构造器ServerSocket
            //2.调用accept()表示接收来自于客户端的socket
            socket = ss.accept();//接收accept()
            //3.获取输入流
            is = socket.getInputStream();//输入流getInputStream()

            //不建议这样写,可能会乱码,因为要是传过来的文字,且内容大于数组长度便会乱码
//        byte[] buffer = new byte[1024];
//        int len;
//        while((len = is.read(buffer)) != -1){
//            String str = new String(buffer,0,len);
//            System.out.print(str);
//        }
            //4.读取输入流中的数据
            baos = new ByteArrayOutputStream();//自带数组,不够自动扩容
            byte[] buffer = new byte[5];
            int len;
            while((len = is.read(buffer)) != -1){
                baos.write(buffer,0,len);
                //尽管一次写入5个字节,但其实是将所有字节写入后才整体拼接转换成文字
            }
            System.out.println(baos.toString());//整体输出

            System.out.println("收到了来自于:" + socket.getInetAddress().getHostAddress() + "的数据");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(baos != null){
                //5.关闭资源
                    baos.close();                
                    is.close();
                    socket.close();
                    ss.close();
            }
        }
    }

例题二

//客户端发送文件给服务端,服务端将文件保存在本地。
@Test
public void client() throws IOException {
    //1.
    Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
    //2.
    OutputStream os = socket.getOutputStream();//往外输出数据
    //3.
    FileInputStream fis = new FileInputStream(new File("beauty.jpg"));//先读取一个文件
    //4.
    byte[] buffer = new byte[1024];
    int len;
    while((len = fis.read(buffer)) != -1){//读取文件
        os.write(buffer,0,len);//将文件写出去
    }
    //5.
    fis.close();
    os.close();
    socket.close();
}
/*
这里涉及到的异常,应该使用try-catch-finally处理
 */
@Test
public void server() throws IOException {
    //1.
    ServerSocket ss = new ServerSocket(9090);
    //2.
    Socket socket = ss.accept();
    //3.
    InputStream is = socket.getInputStream();//用于接收数据
    //4.
    FileOutputStream fos = new FileOutputStream(new File("beauty1.jpg"));//将传过来的文件保存在本地
    //5.
    byte[] buffer = new byte[1024];
    int len;
    while((len = is.read(buffer)) != -1){//读取客户端传来的数据
        fos.write(buffer,0,len);//将数据写到本地,用于浏览
    }
    //6.
    fos.close();
    is.close();
    socket.close();
    ss.close();
}

例题三

//从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。

/*
    这里涉及到的异常,应该使用try-catch-finally处理
     */
@Test
public void client() throws IOException {
    //1.
    Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9090);
    //2.
    OutputStream os = socket.getOutputStream();
    //3.
    FileInputStream fis = new FileInputStream(new File("beauty.jpg"));
    //4.
    byte[] buffer = new byte[1024];
    int len;
    while((len = fis.read(buffer)) != -1){
        os.write(buffer,0,len);
    }
    //关闭数据的输出,所以当客户端传输完成之后需要手动添加关闭socket服务
    socket.shutdownOutput();

    //5.接收来自于服务器端的数据,并显示到控制台上
    InputStream is = socket.getInputStream();
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] bufferr = new byte[20];
    int len1;
    while((len1 = is.read(buffer)) != -1){
        baos.write(buffer,0,len1);
    }

    System.out.println(baos.toString());

    //6.
    fis.close();
    os.close();
    socket.close();
    baos.close();
}

/*
这里涉及到的异常,应该使用try-catch-finally处理
 */
@Test
public void server() throws IOException {
    //1.
    ServerSocket ss = new ServerSocket(9090);
    //2.
    Socket socket = ss.accept();
    //3.
    InputStream is = socket.getInputStream();
    //4.
    FileOutputStream fos = new FileOutputStream(new File("beauty2.jpg"));
    //5.
    byte[] buffer = new byte[1024];
    int len;
    while((len = is.read(buffer)) != -1){//服务器端不会自动结束退出循环,因为其一直等待客户端的持续发送,不知道客户端什么时候结束,所以不会退出循环
        //当关闭socket服务,就让服务端知道客户端不再发数据,因此退出循环,才能走下一步的回复客户端
        fos.write(buffer,0,len);
    }

    System.out.println("图片传输完成");

    //6.服务器端给予客户端反馈
    OutputStream os = socket.getOutputStream();
    os.write("你好,美女,照片我已收到,非常漂亮!".getBytes());

    //7.
    fos.close();
    is.close();
    socket.close();
    ss.close();
    os.close();
}
UDP示例
//发送端
@Test
public void sender() throws IOException {
    DatagramSocket socket = new DatagramSocket();
    String str = "我是UDP方式发送的导弹";
    byte[] data = str.getBytes();
    InetAddress inet = InetAddress.getLocalHost();
    DatagramPacket packet = new DatagramPacket(data,0,data.length,inet,9090);
    socket.send(packet);
    socket.close();
}
//接收端
@Test
public void receiver() throws IOException {
    DatagramSocket socket = new DatagramSocket(9090);
    byte[] buffer = new byte[100];
    DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
    socket.receive(packet);
    System.out.println(new String(packet.getData(),0,packet.getLength()));
    socket.close();
}

URL编程

​ url:统一资源定位符,对应着互联网的某一资源地址

基本结构

  • http://localhost:8080/examples/beauty.jpg?username=Tom
  • 协议**//主机名 端口号/ 资源地址/ ** 参数列表

实例化

URL url = new URL(“http://localhost:8080/examples/beauty.jpg?username=Tom”);

方法

在这里插入图片描述

读取下载

public static void main(String[] args) {

    HttpURLConnection urlConnection = null;
    InputStream is = null;
    FileOutputStream fos = null;
    try {
        URL url = new URL("http://localhost:8080/examples/beauty.jpg");

        urlConnection = (HttpURLConnection) url.openConnection();

        urlConnection.connect();

        is = urlConnection.getInputStream();
        fos = new FileOutputStream("day10\\beauty3.jpg");

        byte[] buffer = new byte[1024];
        int len;
        while((len = is.read(buffer)) != -1){
            fos.write(buffer,0,len);
        }

        System.out.println("下载完成");
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        //关闭资源
        if(is != null){
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(fos != null){
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if(urlConnection != null){
            urlConnection.disconnect();
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaSE网络编程采用的是基于TCP/IP协议的网络模型。这个模型包括客户端和服务器端两部分。客户端通过套接字(Socket)与服务器建立连接,服务器则监听客户端的连接请求并进行响应。 在Java中,可以使用Socket类和ServerSocket类来实现网络编程。Socket类用于建立客户端与服务器之间的通信连接,而ServerSocket类则用于创建服务器端的套接字,监听并接受客户端的连接请求。 客户端通过创建Socket对象,指定服务器的IP地址和端口号,然后通过Socket对象的方法与服务器进行通信。服务器端通过创建ServerSocket对象,指定服务器要监听的端口号,并通过accept()方法接受客户端的连接请求。一旦建立了连接,客户端和服务器端就可以通过输入流和输出流来进行数据的传输。 网络模型是基于TCP/IP协议的,因此可以使用Java的InputStream和OutputStream来进行数据的读写。客户端可以通过InputStream从服务器端接收数据,通过OutputStream向服务器端发送数据。服务器端则可以通过InputStream接收客户端发送的数据,通过OutputStream向客户端发送数据。 总结来说,JavaSE网络编程采用的是基于TCP/IP协议的网络模型,通过Socket和ServerSocket来实现客户端和服务器端之间的通信。通过InputStream和OutputStream来进行数据的读写。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [JavaSE——网络编程](https://blog.csdn.net/yzl1293346757/article/details/126192384)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaSE学习——网络编程](https://blog.csdn.net/Demon_and_Angle_/article/details/126387829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值