网络编程(Socket编程)

IP和PORT
IP的简介和分类
简介
IP(Internet Protocol)网络互联协议(互联网协议),是TCP/IP协议组的核心协议之一。IP和子网掩码构成了一台计算机在一个网络中的唯一识别。IP有IPv4和IPv6之分,这里重点说IPv4,IPv4的IP通常由4个十进制数字表示:xxx.xxx.xxx.xxx xxx在底层用二进制表示是一个字节(Byte),一个字节是8bit位 ,xxx用二进制表示取值范围就是0000 0000 --1111 11111 ,就是2的8次256个数字,因为从0开始,最大到255。
分类

端口(port)的简介和分类
简介
PORT(端口)是计算机的逻辑概念。上面使用IP能找到一台电脑,端口(Port)就是这台电脑上的网络服务或者网络应用的唯一识别。
端口在底层通常使用2个字节(1Byte=8bit)来表示,最大的表示的端口数就是2的16次方65536。但是端口是从0开始,最大的端口就是65535。
例如:tomcat 8080 ftp 21 ssh 22 http 80 https 443 mysql 3306
分类

TCP和UDP

TCP概念和特点
TCP(Transmission Control Protocol) 传输控制协议。面相链接编程,占用资源高,数据可靠性好,底层使用IO流进行数据传输,支持一对一,不支持广播(一对多)。
UDP概念和特点
UDP(User Datagram Protocol)用户数据报协议。面相无连接编程,占用资源低,数据可靠性差,底层使用数据报进行数据传输,支持一对一,也支持广播(一对多)。

java TCP编程
工作流程
服务端
1,使用端口号,实例化ServerSocket,为数据传输做准备
2,调用ServerSocker中的accept方法,等待客户端传入数据(没有传入数据之前一直等待)
3,使用InputStream接口接收客户端输入数据
4,使用OutStream接口向客户端输出数据
5,关闭资源
客户端
1,使用IP和PORT端口创建Socket对象,为数据传输做准备
2,使用OutputStream接口向服务端输出数据
3,使用InputStream接口接受服务端输入的数据
4,关闭资源

简单数据传输示例
服务端

package com.aaa.tcp.demo1;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * @FileName: Server
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 10:55
 * @Version: 1.0.0
 */
public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket =  null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
            //1,使用端口号,实例化ServerSocket,为数据传输做准备
            //ServerSocket 这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求。
            // 它根据该请求执行一些操作,然后可能将结果返回给请求者。
            //Socket  该类实现客户端套接字(也称为“套接字”)。 套接字是两台机器之间通讯的端点。
            serverSocket = new ServerSocket(18888);//端口  1024-49151
                //打印提示
            System.out.println("服务器已经准备就绪,等待客户端传入数据!!!!");
            //2,调用ServerSocker中的accept方法,等待客户端传入数据(没有传入数据之前一直等待)
               //accept()  侦听要连接到此套接字并接受它。 该方法将阻塞直到建立连接。
            socket = serverSocket.accept();
            //3,使用InputStream接口接收客户端输入数据
            inputStream = socket.getInputStream();
               //可能要传输中文,最好使用字符流进行接受,避免中文乱码 把字节流转成字符流
               //为了提高字符流的读写效率,可以在流上套接缓冲流,提高读写速度
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
               //bufferedReader支持按行读取
            String clietMsg = bufferedReader.readLine();
               //打印信息
            System.out.println("客户端说:"+clietMsg);
            //4,使用OutStream接口向客户端输出数据
            outputStream = socket.getOutputStream();
            //直接使用outputStream 响应客户端,如果传递中文可能会乱码,不能按行响应,套接上 printWriter 可以直接按行响应
            printWriter = new PrintWriter(outputStream);
             //向客户端打印
            printWriter.println("客户端:你好,你发送的"+clietMsg+"信息,我已经收到!");
             //刷新管道
            printWriter.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //5,关闭资源    关闭流的原则:先打开的后关闭,有套接关系的,先关闭被套接的流
                if(outputStream!=null){
                    outputStream.close();
                }

                if(inputStream!=null){
                    inputStream.close();
                }
                if(bufferedReader!=null){
                    bufferedReader.close();
                }

                if(socket!=null){
                    socket.close();
                }
                if(serverSocket!=null){
                    serverSocket.close();
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

客户端

package com.aaa.tcp.demo1;

import java.io.*;
import java.net.Socket;

/**
 * @FileName: Client
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 14:06
 * @Version: 1.0.0
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        try {
            //1,使用IP和PORT端口创建Socket对象,为数据传输做准备
            //创建流套接字并将其连接到指定主机上的指定端口号。
            // Socket socket = new Socket("localhost",18888);
            // Socket socket = new Socket("127.0.0.1",18888);
            socket = new Socket("172.16.2.75",18888);
            //2,使用OutputStream接口向服务端输出数据
            outputStream = socket.getOutputStream();
            printWriter = new PrintWriter(outputStream);
            printWriter.println("你好!");
            //刷新管道
            printWriter.flush();
            //3,使用InputStream接口接受服务端输入的数据
            inputStream = socket.getInputStream();
            //转字符流,套接缓冲流
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
            //读取并打印
            String sererMsg = bufferedReader.readLine();
            System.out.println("服务器说:"+sererMsg);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //4,关闭资源
            try {
                if(inputStream!=null){
                    inputStream.close();
                }
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
                if(outputStream!=null){
                    outputStream.close();
                }
                if(printWriter!=null){
                    printWriter.close();
                }
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

控制台对聊

服务器

package com.aaa.tcp.demo2;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

/**
 * @FileName: Server
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 10:55
 * @Version: 1.0.0
 */
public class Server {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket =  null;
        InputStream inputStream = null;
        OutputStream outputStream = null;
        BufferedReader bufferedReader = null;
        PrintWriter printWriter = null;
        try {
            //1,使用端口号,实例化ServerSocket,为数据传输做准备
            //ServerSocket 这个类实现了服务器套接字。 服务器套接字等待通过网络进入的请求。
            // 它根据该请求执行一些操作,然后可能将结果返回给请求者。
            //Socket  该类实现客户端套接字(也称为“套接字”)。 套接字是两台机器之间通讯的端点。
            serverSocket = new ServerSocket(19999);//端口  1024-49151
                //打印提示
            System.out.println("服务器已经准备就绪,等待客户端传入数据!!!!");
            //2,调用ServerSocker中的accept方法,等待客户端传入数据(没有传入数据之前一直等待)
               //accept()  侦听要连接到此套接字并接受它。 该方法将阻塞直到建立连接。
            socket = serverSocket.accept();
            //3,使用InputStream接口接收客户端输入数据
            inputStream = socket.getInputStream();
               //可能要传输中文,最好使用字符流进行接受,避免中文乱码 把字节流转成字符流
               //为了提高字符流的读写效率,可以在流上套接缓冲流,提高读写速度
               // 支持中文:GBK = big5 大五码(繁体字,中国香港,台湾使用比较多) +gb2312(简体字)   gb2312(guo biao)   gbk(guo biao kuo)
               //  不支持中文:  ISO-8859-1
                //   Unicode编码:万国码,国际码     utf-8   unicode拓展码   支持全世界各国的语言的
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
            //4,使用OutStream接口向客户端输出数据
            outputStream = socket.getOutputStream();
            //直接使用outputStream 响应客户端,如果传递中文可能会乱码,不能按行响应,套接上 printWriter 可以直接按行响应
            printWriter = new PrintWriter(outputStream);
            //实例化扫描器类
            Scanner scanner = new Scanner(System.in);

            //使用死循环一直读取客户端信息
            while (true) {
                //bufferedReader支持按行读取
                String clietMsg = bufferedReader.readLine();
                //打印信息
                System.out.println("客户端说:" + clietMsg);
                //判断客户端的信息,如果含有借钱 就退出
                if(clietMsg.contains("借钱")){
                    //向客户端打印
                    printWriter.println("你被拉黑了");
                    //刷新管道
                    printWriter.flush();
                    break;
                }
                //打印提示
                System.out.println("请输入:");
                //收集控制台信息,输入之前一直阻塞
                String inputMsg = scanner.next();
                //向客户端打印
                printWriter.println(inputMsg);
                //刷新管道
                printWriter.flush();
            }


        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                //5,关闭资源    关闭流的原则:先打开的后关闭,有套接关系的,先关闭被套接的流
                if(outputStream!=null){
                    outputStream.close();
                }

                if(inputStream!=null){
                    inputStream.close();
                }
                if(bufferedReader!=null){
                    bufferedReader.close();
                }

                if(socket!=null){
                    socket.close();
                }
                if(serverSocket!=null){
                    serverSocket.close();
                }

            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

客户端

package com.aaa.tcp.demo2;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

/**
 * @FileName: Client
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 14:06
 * @Version: 1.0.0
 */
public class Client {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream outputStream = null;
        PrintWriter printWriter = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        try {
            //1,使用IP和PORT端口创建Socket对象,为数据传输做准备
            //创建流套接字并将其连接到指定主机上的指定端口号。
            // Socket socket = new Socket("localhost",18888);
            // Socket socket = new Socket("127.0.0.1",18888);
            socket = new Socket("172.16.2.75",19999);
            //2,使用OutputStream接口向服务端输出数据
            outputStream = socket.getOutputStream();
            printWriter = new PrintWriter(outputStream);


            //3,使用InputStream接口接受服务端输入的数据
            inputStream = socket.getInputStream();
            //转字符流,套接缓冲流
            bufferedReader = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));

            //实例化扫描器类
            Scanner scanner = new Scanner(System.in);
            //使用死循环一直读取客户端信息
            while (true) {
                //打印提示
                System.out.println("请输入:");
                //收集控制台信息,输入之前一直阻塞
                String inputMsg = scanner.next();
                printWriter.println(inputMsg);
                //刷新管道
                printWriter.flush();
                //读取并打印
                String sererMsg = bufferedReader.readLine();
                System.out.println("服务器说:"+sererMsg);
                //判断客户端的信息,如果含有借钱 就退出
                if(sererMsg.contains("拉黑")){
                    //向客户端打印
                    printWriter.println("借钱");
                    //刷新管道
                    printWriter.flush();
                    break;
                }
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //4,关闭资源
            try {
                if(inputStream!=null){
                    inputStream.close();
                }
                if(bufferedReader!=null){
                    bufferedReader.close();
                }
                if(outputStream!=null){
                    outputStream.close();
                }
                if(printWriter!=null){
                    printWriter.close();
                }
                if(socket!=null){
                    socket.close();
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

    }
}

java UDP编程
工作流程

简单例子
服务端

package com.aaa.udp.demo1;

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

/**
 * @FileName: Server
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 16:25
 * @Version: 1.0.0
 */
public class Server {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            //1,实例化数据的发送或者接收对象DatagramSocket
                //DatagramSocket  此类表示用于发送和接收数据报数据包的套接字。
            datagramSocket = new DatagramSocket();
            //2,准备发送数据
            String sendMessage = "hello qy178!!!你好,中国!!!";
                //转换为数组
            byte[] sendMessageByteArray = sendMessage.getBytes("utf-8");
            //3,封装数据报包对象DatagramPacket
               //DatagramPacket 该类表示数据报包。
                //getByName 返回值就是InetAddress的对象
            DatagramPacket datagramPacket =new DatagramPacket(sendMessageByteArray,sendMessageByteArray.length
            , InetAddress.getByName("172.16.2.75"),16868);
            //4,发送数据
            datagramSocket.send(datagramPacket);
                //打印提示
            System.out.println("数据发送完成!");
        } catch (SocketException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //5,关闭资源
            if(datagramSocket!=null) {
                datagramSocket.close();
            }
        }

    }
}

客户端

package com.aaa.udp.demo1;

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

/**
 * @FileName: Client
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 16:25
 * @Version: 1.0.0
 */
public class Client {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {

            //1,实例化数据的发送或者接收对象DatagramSocket
            datagramSocket = new DatagramSocket(16868);
            // hello qy178!!!你好,中国!!!
            //2,准备字节缓冲数组  [h,e,l,l,o, ,q, ....,!]      A=67  a=96
            byte[] receiveMsgByteArray = new byte[2048];
            //3,封装接受数据对象DatagramPackage,接受数据
            DatagramPacket datagramPacket =new DatagramPacket(receiveMsgByteArray,2048);
               //打印提示
            System.out.println("客户端等待接受数据!!!!!!!!");
               // receive 从此套接字接收数据报包。 当此方法返回时, DatagramPacket的缓冲区将填充接收到的数据。
                //该方法阻塞,直到接收到数据报。
            datagramSocket.receive(datagramPacket);
            //4,组装数组并打印
              //datagramPacket.getLength()  返回要发送的数据的长度或接收到的数据的长度。
            String receiveMsg = new String(receiveMsgByteArray, 0, datagramPacket.getLength(), "utf-8");
            System.out.println("接受到的数据为:"+receiveMsg);
        } catch (SocketException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //5,关闭资源
            if(datagramSocket!=null){
                datagramSocket.close();
            }
        }


    }

}

广播例子
需求
编写发送震动飞秋的代码,让局域网内的所有飞秋同时震动!

package com.aaa.udp.demo2;

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

/**
 * @FileName: Server
 * @Description:
 * @Author: zhz
 * @CreateTime: 2024/11/22 17:10
 * @Version: 1.0.0
 */
public class Server {
    public static void main(String[] args) {
        DatagramSocket datagramSocket = null;
        try {
            //1,实例化数据的发送或者接收对象DatagramSocket
            //DatagramSocket  此类表示用于发送和接收数据报数据包的套接字。
            datagramSocket = new DatagramSocket();
            //2,准备发送数据
            String sendMessage = "1_lbt4_0#128#000C29D68D8F#0#0#0#2.5a:1399716676:%s:%s:209:.";
            //转换为数组
            byte[] sendMessageByteArray = sendMessage.getBytes("utf-8");
            while (true) {
                for (int i = 3; i <= 254; i++) {
                    //3,封装数据报包对象DatagramPacket
                    //DatagramPacket 该类表示数据报包。
                    //getByName 返回值就是InetAddress的对象
                    DatagramPacket datagramPacket = new DatagramPacket(sendMessageByteArray, sendMessageByteArray.length
                            , InetAddress.getByName("172.16.2." + i), 2425);
                    //4,发送数据
                    datagramSocket.send(datagramPacket);
                }
                Thread.sleep(3000);
                //打印提示
                System.out.println("数据发送完成!");
            }

        } catch (SocketException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            //5,关闭资源
            if(datagramSocket!=null) {
                datagramSocket.close();
            }
        }

    }
}

posted on 2024-12-29 16:15  小木不痞  阅读(78)  评论(0)    收藏  举报

导航