05.Java网络编程(代码实践)

简介: 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路链接起来,在网络操作系统,网络管理软件及网络通信协议的协调下,实现资源贡献和信息传递的计算机系统网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换网...

计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路链接起来,在网络操作系统,网络管理软件及网络通信协议的协调下,实现资源贡献和信息传递的计算机系统

网络编程就是用来实现网络互连的不同计算机上运行的程序间可以进行数据交换

网络编程三要素:

IP:每个设备在网络中的唯一标识,每台网络终端在网络中都有一个独立的地址,我们在网络中传输数据就是使用这个地址
ipconfig:查看本机IP地址,ipv4地址
ping:测试连接

端口:每个程序在设备上的唯一标识,每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发送到哪台机器上,还需要确定发送到哪个程序,端口号范围:0~65535,编写的网络应用端口号尽量设置1024以上的,1024之下的基本上都被系统程序占用了

协议:为计算机网络进行数据交换而建立的规则,标准或约定的集合
UDP:面向无连接,数据不安全,速度快,不区分客户端与服务端
TCP:面向链接,三次握手,数据安全但效率低,分为客户端和服务端,三次握手的过程,客户端向服务端发起请求,服务端响应请求,传输数据

Socke套接字通信:

网络上具有唯一标识的IP地址和端口号组合在一起,才能构成唯一能识别的标识符套接字
通信的两端都有socket,网络通信其实就是socket间的通信,它通过IO流进行传输,Socket在应用程序中创建,通过一种绑定机制与驱动机制建立关系,告诉自己所对应的IP和端口

新建一个Java工程模拟UDP通信


img_267f1b14280c52d012826235fc855759.png
图片1.png
package com.ren.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Scanner;
/**
 * socket好比发货的码头,packet就是需要发送的集装箱货物,这个货物需要发送到哪里,它的地址
 * 信息是在货物上标明的,所以packet构造方法上传递了发送目的地的地址和该地址上接收程序的端口
 * @author renzhenming
 *
 */
public class Send {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        DatagramSocket socket = new DatagramSocket();
        
        while(true){
            String scan = sc.nextLine();
            DatagramPacket packet = 
                    new DatagramPacket(scan.getBytes(), //或者用127.0.0.1也可以
                            scan.getBytes().length, InetAddress.getByName("192.168.1.103"), 9999);
            socket.send(packet);
        }
    }

}
package com.ren.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * 创建接收端
 * @author renzhenming
 *
 */
public class Receive {

    public static void main(String[] args) throws IOException {
        //用于接收传递过来的数据
        DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
        //指定端口号,用于接收指定端口传递的数据
        DatagramSocket socket = new DatagramSocket(9999);
        
        while(true){
            //执行之后会将接收到的数据放在packet中
            socket.receive(packet);
            //转换成字符串打印
            byte[] arr = packet.getData();
            int len = packet.getLength();
            String ip = packet.getAddress().getHostAddress();
            int port = packet.getPort();
            System.out.println(ip+":"+port+":"+new String(arr,0,len));
        }
    }
}

为了演示效果,我们打开两个命令行,在命令行中分别执行这两个Java方法,先执行Receive端,注意要在bin目录下运行命令


img_cfa1932858998c475d6890b2dc849f0c.png
图片1.png

开启线程执行

package com.ren.socket;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Scanner;
/**
 * socket好比发货的码头,packet就是需要发送的集装箱货物,这个货物需要发送到哪里,它的地址
 * 信息是在货物上标明的,所以packet构造方法上传递了发送目的地的地址和该地址上接收程序的端口
 * @author renzhenming
 *
 */
public class SocketDemo {

    public static void main(String[] args) throws IOException {
        new Receive().start();
        new Sender().start();
    }
}

class Receive extends Thread{
    @Override
    public void run() {
        super.run();
        try {
            //用于接收传递过来的数据
            DatagramPacket packet = new DatagramPacket(new byte[1024], 1024);
            //指定端口号,用于接收指定端口传递的数据
            DatagramSocket socket = new DatagramSocket(9999);
                    
            while(true){
                //执行之后会将接收到的数据放在packet中
                socket.receive(packet);
                //转换成字符串打印
                byte[] arr = packet.getData();
                int len = packet.getLength();
                String ip = packet.getAddress().getHostAddress();
                int port = packet.getPort();
                System.out.println(ip+":"+port+":"+new String(arr,0,len));
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

class Sender extends Thread{
    @Override
    public void run() {
        super.run();
        try {
            Scanner sc = new Scanner(System.in);
            DatagramSocket socket = new DatagramSocket();
            
            while(true){
                String scan = sc.nextLine();
                DatagramPacket packet = 
                        new DatagramPacket(scan.getBytes(), //或者用127.0.0.1也可以
                                scan.getBytes().length, InetAddress.getByName("192.168.1.103"), 9999);
                socket.send(packet);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

新建一个Java工程模拟TCP通信
TCP协议的Socket通信,客户端通过Socket处理发送和接收,服务端通过ServerSocket 处理发送和接收

Socket_TCP_Client

package com.ren.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.net.UnknownHostException;

public class Socket_TCP_Client {

    public static void main(String[] args) throws UnknownHostException, IOException {
        //socket1();
        socket2();
    }
    //多个
    private static void socket2() throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1",12345);
        BufferedReader br = new BufferedReader
                (new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        
        System.out.println(br.readLine());
        ps.println("我可以去哪里逛逛呢");
        System.out.println(br.readLine());
        ps.println("谢谢");
        socket.close();
        
    }

    //一次读取一个
    private static void socket1() throws UnknownHostException, IOException {
        Socket socket = new Socket("127.0.0.1",12345);
        //输入流可以读取服务端输出流写出的数据
        InputStream in = socket.getInputStream();
        //输出流可以写出数据到服务端输入流
        OutputStream out = socket.getOutputStream();
        out.write("打开百度首页".getBytes());
        byte[] arr = new byte[1024];
        int len = in.read(arr);
        System.out.println("收到服务端数据:"+new String(arr,0,len));
    }

}

Socket_TCP_Server

package com.ren.socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;

public class Socket_TCP_Server {

    public static void main(String[] args) throws Exception {
        //socket1();
        //socket2();
        socket3();
    }
    //多线程开启服务器,可以接收多个客户端来咨询
    private static void socket3() throws IOException {
        final ServerSocket serverSocket = new ServerSocket(12345);
        
        while(true){
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    
                    try {
                        Socket socket = serverSocket.accept();
                        BufferedReader br = new BufferedReader
                                (new InputStreamReader(socket.getInputStream()));
                        PrintStream ps = new PrintStream(socket.getOutputStream());
                        
                        ps.println("欢迎来到中国");
                        //readLine是以换行为结束符读取一行数据的,如果客户端写入数据的时候使用了print而不是println,就会导致
                        //数据无法读取
                        System.out.println(br.readLine());
                        ps.println("你可以先去游览北京长城");
                        System.out.println(br.readLine());
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
        
        
    }

    //实现多次读取
    private static void socket2() throws Exception {
        ServerSocket serverSocket = new ServerSocket(12345);
        Socket socket = serverSocket.accept();
        
        BufferedReader br = new BufferedReader
                (new InputStreamReader(socket.getInputStream()));
        PrintStream ps = new PrintStream(socket.getOutputStream());
        
        ps.println("欢迎来到中国");
        //readLine是以换行为结束符读取一行数据的,如果客户端写入数据的时候使用了print而不是println,就会导致
        //数据无法读取
        System.out.println(br.readLine());
        ps.println("你可以先去游览北京长城");
        System.out.println(br.readLine());
        socket.close();

    }

    //实现单词读取
    private static void socket1() throws IOException {
        //注意端口号不能超过65535
        ServerSocket server = new ServerSocket(12345);
        //接收服务端数据,这个操作会阻塞线程,直到收到数据才往下执行
        Socket socket = server.accept();
        //接收到的客户端消息
        InputStream is = socket.getInputStream();
        byte[] arr = new byte[1024];
        int len = is.read(arr);
        System.out.println("收到客户端数据:"+new String(arr,0,len));
        //向客户端发送消息需要获取一个输入流然后write
        OutputStream os = socket.getOutputStream();
        os.write("百度一下,你就知道".getBytes());
    }

}
相关文章
|
11天前
|
Java 程序员
JAVA程序员的进阶之路:掌握URL与URLConnection,轻松玩转网络资源!
在Java编程中,网络资源的获取与处理至关重要。本文介绍了如何使用URL与URLConnection高效、准确地获取网络资源。首先,通过`java.net.URL`类定位网络资源;其次,利用`URLConnection`类实现资源的读取与写入。文章还提供了最佳实践,包括异常处理、连接池、超时设置和请求头与响应头的合理配置,帮助Java程序员提升技能,应对复杂网络编程场景。
34 9
|
11天前
|
人工智能 Java 物联网
JAVA网络编程的未来:URL与URLConnection的无限可能,你准备好了吗?
随着技术的发展和互联网的普及,JAVA网络编程迎来新的机遇。本文通过案例分析,探讨URL与URLConnection在智能API调用和实时数据流处理中的关键作用,展望其未来趋势和潜力。
34 7
|
11天前
|
Java 开发者
JAVA高手必备:URL与URLConnection,解锁网络资源的终极秘籍!
在Java网络编程中,URL和URLConnection是两大关键技术,能够帮助开发者轻松处理网络资源。本文通过两个案例,深入解析了如何使用URL和URLConnection从网站抓取数据和发送POST请求上传数据,助力你成为真正的JAVA高手。
29 11
|
11天前
|
安全 Java API
深入探索Java网络编程中的HttpURLConnection:从基础到进阶
本文介绍了Java网络编程中HttpURLConnection的高级特性,包括灵活使用不同HTTP方法、处理重定向、管理Cookie、优化安全性以及处理大文件上传和下载。通过解答五个常见问题,帮助开发者提升网络编程的效率和安全性。
|
11天前
|
JSON 安全 算法
JAVA网络编程中的URL与URLConnection:那些你不知道的秘密!
在Java网络编程中,URL与URLConnection是连接网络资源的两大基石。本文通过问题解答形式,揭示了它们的深层秘密,包括特殊字符处理、请求头设置、响应体读取、支持的HTTP方法及性能优化技巧,帮助你掌握高效、安全的网络编程技能。
39 9
|
6天前
|
数据采集 存储 XML
Python实现网络爬虫自动化:从基础到实践
本文将介绍如何使用Python编写网络爬虫,从最基础的请求与解析,到自动化爬取并处理复杂数据。我们将通过实例展示如何抓取网页内容、解析数据、处理图片文件等常用爬虫任务。
|
11天前
|
JSON Java API
JAVA网络编程新纪元:URL与URLConnection的神级运用,你真的会了吗?
本文深入探讨了Java网络编程中URL和URLConnection的高级应用,通过示例代码展示了如何解析URL、发送GET请求并读取响应内容。文章挑战了传统认知,帮助读者更好地理解和运用这两个基础组件,提升网络编程能力。
33 5
|
3天前
|
边缘计算 5G 数据处理
5G网络能耗管理:绿色通信的实践
【10月更文挑战第30天】
14 0
|
9天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
4天前
|
存储 设计模式 分布式计算
Java中的多线程编程:并发与并行的深度解析####
在当今软件开发领域,多线程编程已成为提升应用性能、响应速度及资源利用率的关键手段之一。本文将深入探讨Java平台上的多线程机制,从基础概念到高级应用,全面解析并发与并行编程的核心理念、实现方式及其在实际项目中的应用策略。不同于常规摘要的简洁概述,本文旨在通过详尽的技术剖析,为读者构建一个系统化的多线程知识框架,辅以生动实例,让抽象概念具体化,复杂问题简单化。 ####