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

猜你喜欢

转载自blog.csdn.net/weixin_45963193/article/details/114080842
今日推荐