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());
    }

}
相关文章
|
2天前
|
数据采集 Java 开发者
JAVA网络编程深度探索:URL与URLConnection的精湛技艺
Java网络编程核心在于URL和URLConnection。URL是资源的唯一标识,用于定位网络资源,支持解析、编码解码及参数操作。URLConnection则实现数据交换,允许GET/POST请求,可定制请求头、设置超时,是网络交互的关键。两者结合,适用于网络爬虫等场景,深入学习能提升编程技巧并揭示网络编程奥秘。
|
1天前
|
网络协议 Java 程序员
TCP/IP协议栈是网络通信基础,Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用
【6月更文挑战第23天】 **TCP/IP协议栈是网络通信基础,它包含应用层(HTTP, FTP等)、传输层(TCP, UDP)、网络层(IP)、数据链路层(帧, MAC地址)和物理层(硬件信号)。Java的`java.net`包提供工具,使开发者能利用TCP/IP创建网络应用,如Socket和ServerSocket用于客户端和服务器通信。**
8 3
|
2天前
|
Java
【思维导图】JAVA网络编程思维升级:URL与URLConnection的逻辑梳理,助你一臂之力!
【6月更文挑战第22天】Java网络编程中,URL是资源定位器,用于解析和创建网络地址;URLConnection接口负责建立到URL资源的连接。示例展示了如何使用URL类获取协议、主机、端口和路径,以及如何通过HttpURLConnection进行GET/POST请求,设置超时并处理响应。思维导图概述了从创建URL到设置请求属性、发送请求及处理响应的完整流程,帮助理解两者在网络编程中的作用。
|
1天前
|
机器学习/深度学习 Java
java中的回溯法问题的详细代码
java中的回溯法问题的详细代码
10 2
|
1天前
|
JSON Java 数据格式
Java中创建Json对象的方法和详细代码
Java中创建Json对象的方法和详细代码
19 1
|
1天前
|
Java 数据处理 Python
Java基础方法和代码解释
Java基础方法和代码解释
|
1天前
|
Java
JAVA随机生成一个汉字的方法和代码
JAVA随机生成一个汉字的方法和代码
|
22小时前
|
Java 编译器
Java中可变长参数的使用代码和方法
Java中可变长参数的使用代码和方法
17 7
|
22小时前
|
存储 安全 Java
Java生成随机数的代码和方法
Java生成随机数的代码和方法
13 6
|
22小时前
|
Java Serverless
Java字符个数统计代码
Java字符个数统计代码
18 6

热门文章

最新文章