柏竹 柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档

柏竹

奋斗柏竹
首页
后端
前端
  • 应用推荐
关于
友链
  • 分类
  • 标签
  • 归档
  • Java基础

    • Java认识
    • 面向对象概述
    • Java API
    • Java三大特性
    • Java类的高级特性
    • Java异常
    • Swing程序设计
    • Java集合类
    • Java I/O
    • Java反射
    • 枚举
    • 泛型
    • Java线程
    • Java网络通信
      • IP地址
      • TCP程序设计
        • 服务器套接字
        • 客户端套接字
      • UDP程序设计
        • 数据包
        • 数据包套接字
        • 组播套接字
      • 代码索引
        • IP操作
        • TCP信息交互
        • UDP信息发放
        • 组播发放
        • TCP多线程访问
    • Java事件
    • AWT绘图
    • Java网页访问
    • XML&JSON
    • Java注解
  • JavaWeb

  • 拓展技术

  • 框架技术

  • 数据库

  • 数据结构

  • Spring

  • SpringMVC

  • SpringBoot

  • SpringClound

  • Ruoyi-Vue-Plus

  • 后端
  • Java基础
柏竹
2020-02-18
目录

Java网络通信

# Java网络通信

# IP地址

Class InetAddress

java.lang.Object java.net.InetAddress

该类表示Internet协议(IP)地址。IP地址是由IP使用的32位或128位无符号数字,一般IPv4格式范围:0.0.0.0~255.255.255.255 特殊IP地址:本地回送地址 不进行网络传输 127.0.0.1 返回本地

InetAddress类常用方法

返回 方法 说明
String getHostName()  获取IP地址的主机名
String getHostAddress() 获取IP地址字符串
InetAddress getByName(String host)  获取与Host对应的InetAddress对象
InetAddress getLocalHost() 返回本主机的InetAddress对象
InetAddress[] getAllByName(String host)  获取指定主机的所有地址

其余的方法自查API

点击代码示例* (IP操作)

# TCP程序设计

TCP网络设计是利用Socket类(套接字)编写通信程序。 PS:套接字可以比作是一个连接装置(工具,像用电器必须要插插头连接才能使用!!

TCP协议进行通信应用程序分为 服务器程序 、 客户机程序

实现流程

1. 创建服务器  实例 `ServerSocket()对象`
2. 等待连接客户端 用服务器套接字 `accept()方法`
3. 连接客户端 实例 `Socket()对象` 
4. 发送信息 或 接收信息 (信息交互的是**字节流**)
   发送信息:用客户端套接字 `getOutputStream()方法` 进行输出
   接收信息 :用客户端套接字 `getInputStream()方法` 进行输入

# 服务器套接字

Class ServerSocket

java.lang.Object java.net.ServerSocket

ServerSocket类 实现了服务器套接字。等待通过网络进入的请求。服务器会根据该请求执行一些操作,然后可能将结果返回给请求者

构造方法

ServerSocket() ServerSocket(int port) ServerSocket(int port, int backlog) ServerSocket(int port, int backlog, InetAddress bindAddr)

port: 端口号 backlog: 请求进入连接队列的最大长度 bindAddr: 服务器将绑定到的本地InetAddress

方法

修饰符 方法 说明
Socket accept() 等待客户端的连接,连接则创建套接字
boolean isBound()  判断ServerSocket的绑定状态
InetAddress getInetAddress()  获取服务器套接字的本地地址
boolean isClosed()  获取服务器套接字的关闭状态
void close() 关闭服务器套接字
void bind(SocketAddress endpoint) 将ServerSocket绑定到特定地址(IP地址、端口号)

其余的方法自查API

# 客户端套接字

Class Socket java.lang.Object java.net.Socket

Socket类 实现客户端套接字, 套接字是两台机器之间通讯的端点

构造方法

Socket()  Socket(IntetAddress address , int port) Socket(String host , int port) 

IntetAddress: IP地址 port: 端口号 host: 主机地址

方法

修饰符 方法 说明
InputStream getInputStream() 获取套接字输入流
OutputStream getOutputStream()  获取套接字输出流
boolean isConnected()  查看套接字是否连接
void close() 关闭套接字
InetAddress getInetAddress() 返回连接主机的地址

其余的方法自查API

点击代码示例* (TCP信息交互)

# UDP程序设计

UDP通讯方式,输出快、支持多人,但数据不能保证完好接收。UDP通信模式是将数据打包(数据包),然后接收人接收数据包查看。(其原理类似于电台广播的发放与收音机的接收!

实现流程

发送端:

  1. 实例UDP DatagramSocket()对象
  2. 实例数据包 DatagramPacket()对象 (必须全参实例,否则无法接收)
  3. 广播式发送 DatagramSocket.send(DatagramPacket data)方法

接收端:

  1. 实例UDP DatagramSocket()对象 绑定端口号 (对应 数据包 中的端口号)
  2. 实例数据包 DatagramPacket()对象 (获取信息为前提,参数随意)
  3. DatagramPacket类的receive()方法接收UDP包
  4. 接收数据包 DatagramSocket.receive(DatagramPacket data)方法 进行接收
  5. 获取字节包中的字节内容 DatagramPacket.getData() (最后进行转换即可)

PS:receive()方法接收数据并返回,如未接收到数据,则阻塞至收到为止!!

# 数据包

Class DatagramPacket

java.lang.Object java.net.DatagramPacket

数据包用于实现无连接分组传送服务(类似于快递运送的包裹

构造方法

DatagramPacket(byte[] bt, int len) DatagramPacket(byte[] bt,int off , int len) DatagramPacket(byte[] bt ,int len ,InetAddress address ,int port) DatagramPacket(byte[] bt ,int off ,int len ,InetAddress address ,int port)

bt: 发送数据(字节流) off: 有效数据 在数组中的起始点 len: 有效数据 在数组中的长度 address: 指定IP(InetAddress 实例对象) port: 端口号

方法

返回 方法 说明
InetAddress getAddress() 获取 对方主机 IP对象
byte[] getData() 获取 数据包
int getLength() 获取 数据包的长度
int getOffset() 获取 数据包 起始偏移量
int getPort() 获取 对方主机 端口
SocketAddress getSocketAddress() 获取 发送方的主机 IP地址 和 端口
void setAddress(InetAddress iaddr) 设置 发送至对方主机 IP
void setData(byte[] buf) 设置 数据包的数据缓冲区
void setData(byte[] buf, int offset, int length) 设置 数据包的数据缓冲区,指定范围的有效数据
void setLength(int length) 设置数据包的长度
void setPort(int iport) 设置 发送至对方主机 端口号
void setSocketAddress(SocketAddress address) 设置 发送至对方主机 SocketAddress对象

# 数据包套接字

Class DatagramSocket

java.lang.Object java.net.DatagramSocket

数据包套接字用于 发送 和 接收 数据包的套接字(类似于运送快递的快递员

构造方法

DatagramSocket()  DatagramSocket(int port) DatagramSocket(int port , InetAddress addr)

port: 端口号 address: IP地址

方法

修饰符 方法 说明
void bind(SocketAddress addr) 绑定地址和端口
void close()  关闭数据套接字
void receive(DatagramPacket p)  套接字接收数据包(有堵塞效果)
void send(DatagramPacket p)  套接字发送数据包

其余的方法自查API

点击代码示例* (UDP信息发放)

# 组播套接字

Class MulticastSocket

java.lang.Object java.net.DatagramSocket java.net.MulticastSocket

播组发送消息时,向该主机和端口发送消息,接收者在播放的前提才能接收到消息

构造方法

MulticastSocket() MulticastSocket(int port)  MulticastSocket(SocketAddress bindaddr)

port: 端口号 bindaddr: SocketAddress对象

方法

返回 方法 说明
void joinGroup(InetAddress addr)  加入广播组
void leaveGroup(InetAdderss addr)  离开广播组
InetAdderss getInterface()  获取数据包接口的IP地址

更多方法自行API

点击代码示例* (组播发放)

# 代码索引

# IP操作

(返回*)

import java.net.InetAddress;
import java.net.UnknownHostException;

public class Address {
    public static void main(String[] args) {
        try {
            InetAddress myip = InetAddress.getLocalHost();
            System.out.println("本机名:"+myip.getHostName());
            System.out.println("本机IP:"+myip.getHostAddress());

            //获取百度的所有IP地址
            InetAddress baiduip[] = InetAddress.getAllByName("www.baidu.com");
            for(InetAddress tmp : baiduip){
                System.out.println("IP:"+tmp.getHostAddress());
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

    }
}


/*
* 
* 运行结果:
* 本机名:LAPTOP-GDSLL8RB
* 本机IP:192.168.43.84
* IP:14.215.177.38
* IP:14.215.177.39
* 
* */

# TCP信息交互

(返回*)

服务端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class MyServer {
    
    /**
     * server - 服务器对象
     * reader - 接收用户信息(缓冲字符输入流)
     * writer - 输出内容(文本输出流)
     * socket - 套接字(进行与客户端数据交互的渠道)
     * count - 记录目前用户数
     */
    private ServerSocket server = null;
    private BufferedReader reader = null;
    private PrintWriter writer = null;
    private Socket socket = null;
    private int count = 0;
    
    public static void main(String[] args) {
        new MyServer().serverStart();
    }
    
    private void serverStart() {
        try {
            server = new ServerSocket(8848);
            System.out.println("服务器已创建! ");
            System.out.println("等待客户端连接。。。");
            socket = server.accept();
            count++;
            System.out.println("一个用户连接!");
    
            /**发送内容
             *  利用字节输出流实例 文本流对象
             */
            writer = new PrintWriter(socket.getOutputStream());
            //注意 : 如果没有及时刷新缓存则会发出的是 空
            writer.println("欢迎连接本服务器!!! ");
            //刷新
            writer.flush();
    
            /** 接收内容
             * 形式: 缓存字符流 <- 字符流 <- 字节流
             */
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("客户端 : " + reader.readLine());
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        
    }
}

/*

服务器已创建! 
等待客户端连接。。。
一个用户连接!
客户端 : 好久不见!

*/

客户端:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class MyClient {
    
    /**
     * writer - 输出内容(文本输出流)
     * reader - 接收用户信息(缓冲字符输入流)
     * socket - 套接字(进行与客户端数据交互的渠道)
     */
    private PrintWriter writer = null;
    private BufferedReader reader = null;
    private Socket socket = null;
    
    private void clientStart() {
        try {
            socket = new Socket("127.0.0.1" , 8848);
            writer = new PrintWriter(socket.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            
            //客户端我写的个简写版的
            printReceiving();
            printAndSend("好久不见!");
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    
    }
    
    //接收内容
    private void printReceiving() {
        try {
            System.out.println("服务端 : " + reader.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    //发送内容
    private void printAndSend(String scr) {
        writer.println(scr);
        writer.flush();
    }
    
    public static void main(String[] args) {
        new MyClient().clientStart();
    }
}

/*

服务端 : 欢迎连接本服务器!!! 

*/

# UDP信息发放

(返回*)

发送端:

package kkb;
import java.io.IOException;
import java.net.*;

// UDP 广播 (发送方

public class MyBroadcast extends Thread {
    
    /**
     * data - 数据包
     * socket - 数据包套接字
     * portPacket - 数据包标签 端口号
     * ipPacket - 数据包标签 IP
     */
    private DatagramPacket data = null;
    private DatagramSocket socket = null;
    private int portPacket  = 4399;
    private InetAddress ipPacket = null;
    
    
    public MyBroadcast() {
        try {
            ipPacket = InetAddress.getByName("127.0.0.1");
            socket = new DatagramSocket();
            System.out.println("UDP服务器已启动!");
        } catch (SocketException | UnknownHostException e) {
            e.printStackTrace();
        }
    }
    

    @Override
    public void run() {
        printAndSend("欢迎来到 柏竹 FM广播间!!!");
        while(true){
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printAndSend("今天天气是晴天!");
        }
        
    }
    
    //广播内容
    private void printAndSend(String src) {
        byte[] bt = src.getBytes();
        data = new DatagramPacket(bt ,  bt.length , ipPacket , portPacket);
        try {
            socket.send(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        new MyBroadcast().start();
    }
}

/*
*
* UDP服务器已启动!
*
* */

接收端:

package kkb;

// UDP 广播 (接收方

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

public class MyReceiveUil extends Thread{
    
    /**
     * data - 数据包
     * socket - 数据包套接字
     */
    private DatagramSocket socket = null;
    private int port= 4399;
    
    public MyReceiveUil(){
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        while (true){
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printData(getData());
        }
    }
    
    private void printData(DatagramPacket data) {
        try {
            socket.receive(data);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String scr = new String(data.getData() , 0 , data.getLength());
        System.out.println(scr);
    }
    
    private DatagramPacket getData() {
        byte[] bt = new byte[1024];
        return new DatagramPacket(bt , bt.length);
    }
    
    
    public static void main(String[] args) {
        new MyReceiveUil().start();
    }
}

/*
 
 欢迎来到 柏竹 FM广播间!!!
今天天气是晴天!
今天天气是晴天!
·····

 */

# 组播发放

(返回*)

发送报:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;

//UDP广播 (发送报

public class UdpBroadcastTest extends Thread{

    //广播类
    private MulticastSocket socket;
    //端口号
    private int port = 2233;
    //广播组IP
    private InetAddress group;

    public UdpBroadcastTest(){
        try {
            //给定IP地址
            group = InetAddress.getByName("224.233.2.1");
            socket = new MulticastSocket(port);
                socket.joinGroup(group);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        //数据包
        DatagramPacket packet;
        while (true) {
            SimpleDateFormat date = new SimpleDateFormat("HH:mm:ss");
            String scr =  "["+ date.format(new Date())+ "] 今天天气晴天!!";
            byte[] bt = scr.getBytes();
            packet = new DatagramPacket(bt , bt.length , group , port);
            try {
                socket.send(packet);
                Thread.sleep(2000);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new UdpBroadcastTest().start();
    }
}

/*运行结果为窗体形式*/

接收报:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

//UDP广播 (接收报

public class UdpReceiveTest extends JFrame implements Runnable,ActionListener {

    //初始化数值
    //广播类
    private MulticastSocket socket = null;
    //广播地址组
    private InetAddress group = null;
    private int port = 2233;
    private JButton
        ince = new JButton("开始接收"),
        stop = new JButton("停止接收");
    //文本域
    private JTextArea
            inceAr = new JTextArea(10,10),
            inced = new JTextArea(10,10);
    private JScrollPane
            jspinceAr = null,
            jspinced = null;
    private Thread t;
    //广播关闭 (开关
    private boolean ReceiveSwitch = false;
    private Container c = getContentPane();

    public UdpReceiveTest(){
        super("广播数据报");
        t = new Thread(this);
        setDefaultCloseOperation(3);
        setBounds(400 , 300 , 500 , 380);

        //聚集作用的面板(按钮
        ince.addActionListener(this);
        stop.addActionListener(this);
        JPanel north = new JPanel();
        north.add(ince);
        north.add(stop);
        c.add(north , BorderLayout.NORTH);

        //聚集作用的面板(文本域
        inceAr.setForeground(Color.blue);
        inceAr.setFont(new Font("微软雅黑",Font.PLAIN,16));
        inced.setFont(new Font("微软雅黑",Font.PLAIN,16));
        //自动换行+换行不断字
        inceAr.setLineWrap(true);
        inced.setLineWrap(true);
        inceAr.setWrapStyleWord(true);
        inced.setWrapStyleWord(true);
        //文本域 改至滚动面板
        jspinceAr = new JScrollPane(inceAr);
        jspinced = new JScrollPane(inced);
        JPanel center = new JPanel();
        center.add(jspinceAr);
        center.add(jspinced);
        c.add(center , BorderLayout.CENTER);

        //验证所有组件 (刷新作用
        c.validate();

        try {
            group = InetAddress.getByName("224.233.2.1");
            socket = new MulticastSocket(port);
            socket.joinGroup(group);
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        setVisible(true);
    }

    @Override
    public void run() {
        while (true){
            byte data[] = new byte[1024];
            DatagramPacket packet = null;
            String scr = null;
            packet = new DatagramPacket(data , data.length , group , port);
            try {
                //从此套接字接收数据报包
                socket.receive(packet);
                //获取数据
                scr = new String(packet.getData() , 0 , packet.getLength());
                inceAr.setText("正在接收广播内容:\n"+scr);
                inced.append(scr+"\n");
            } catch (IOException e) {
                e.printStackTrace();
            }
            if(ReceiveSwitch){
                break;
            }
        }
    }

    @Override
    public void actionPerformed(ActionEvent e){
        //if点击开始
        if(e.getSource() == ince){
            ince.setBackground(Color.blue);
            stop.setBackground(Color.yellow);
            //判断线程是否已创建
            if(!(t.isAlive())){
                t = new Thread(this);
            }
            t.start();
            ReceiveSwitch = false;
        }
        //if点击停止
        if(e.getSource() == stop){
            stop.setBackground(Color.red);
            ince.setBackground(Color.white);
            ReceiveSwitch = true;
        }
    }

    public static void main(String[] args) {
        new UdpReceiveTest();
    }
}

/*运行结果为窗体形式*/

# TCP多线程访问

服务端:

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import static java.util.concurrent.Executors.*;
public class MyServer extends Thread{
    
    private ServerSocket server = null;
    private Socket socket = null;
    private ExecutorService service = null;
    private int count = 0;
    
    public MyServer() {
        try {
            server = new ServerSocket(9959);
            service = newCachedThreadPool();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("启动...");
    }
    
    @Override
    public void run() {
        
        while (true){
            
            try {
                socket = server.accept();
                System.out.println("一个客户连接");
                count++;
            } catch (IOException e) {
                e.printStackTrace();
            }
            
            service.execute(() -> {
                BufferedReader reader = null;
                PrintWriter writer = null;
                int n = count;
                try {
                    reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                while (true){
                    try {
                        System.out.println(" 家长" + n + " : "+reader.readLine());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            
            
        }
        
    }
    
    public static void main(String[] args) {
        new MyServer().start();
    }
}

/*

启动...
一个客户连接
 家长1 : 你哪里人啊 !?
一个客户连接
 家长2 : 你多大啦 !?
一个客户连接
 家长3 : 你成绩多少分 !?
 家长2 : 你多大啦 !?
 家长1 : 你哪里人啊 !?
 家长2 : 你多大啦 !?
 家长3 : 你成绩多少分 !?
  。。。。。。

*/

客户端 1:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class Client1 extends Thread{
    
    private Socket socket = null;
    private PrintWriter writer = null;
    
    public Client1() {
        try {
            socket = new Socket("127.0.0.1" , 9959);
            writer = new PrintWriter(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        while (true){
            writer.println("你哪里人啊 !?");
            writer.flush();
            try {
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("out");
        }
    }
    
    public static void main(String[] args) {
        new Client1().start();
    }
}

客户端 2:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class Client2 extends Thread{
    
    private Socket socket = null;
    private PrintWriter writer = null;
    
    public Client2() {
        try {
            socket = new Socket("127.0.0.1" , 9959);
            writer = new PrintWriter(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        while (true){
            writer.println("你多大啦 !?");
            writer.flush();
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("out");
        }
    }
    
    public static void main(String[] args) {
        new Client2().start();
    }
}

客户端 3:

import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;

public class Client3 extends Thread{
    
    private Socket socket = null;
    private PrintWriter writer = null;
    
    public Client3() {
        try {
            socket = new Socket("127.0.0.1" , 9959);
            writer = new PrintWriter(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public void run() {
        while (true){
            writer.println("你成绩多少分 !?");
            writer.flush();
            try {
                Thread.sleep(12000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("out");
        } 
    }
    
    public static void main(String[] args) {
        new Client3().start();
    }
}
#Java
上次更新: 2023/03/12, 00:43:49

← Java线程 Java事件→

最近更新
01
HTTPS自动续签
10-21
02
博客搭建-简化版(脚本)
10-20
03
ruoyi-vue-plus-部署篇
07-13
更多文章>
Theme by Vdoing | Copyright © 2019-2024 | 桂ICP备2022009417号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式