首页 > 编程语言 >网络编程

网络编程

时间:2023-08-16 19:32:53浏览次数:20  
标签:java String 编程 request 网络 System import new

网络编程:网络上的主机,通过不同的进程,以编程的方式实现网络通信;

1.Socket套接字

Socket套接字主要针对传输层协议分为下列三类

网络编程_客户端

UDP协议:无连接, 不可靠传输, 面向数据报, 有接收缓冲区,无发送缓冲区,一次最大传输64K;

TCP协议:有连接, 可靠传输 , 面向字节流 , 有接收和发送缓冲区, 大小不受限制

2.UDP数据报套接字编程

UDP版本的回显服务器

1.读取客户端发送来的请求

2.根据请求计算响应

3.把响应写回客户端

4.打印响应处理结果

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;

public class UdpEchoServer {
    //网络编程本质操作网卡 ,在操作系统内核中使用"socket"文件来抽象表示网卡,方便操作
    // DatagramSocket 发送和接收数据报数据包的套接字。 (socket套接字:两台机器之间通讯的端点 )
    private DatagramSocket socket = null;
    public UdpEchoServer(int port) throws SocketException {
        //服务器一定要关联一个具体的端口,客户端才能找到
        socket = new DatagramSocket(port);
    }
    public void start() throws IOException {
        System.out.println("启动服务器");
        //给多个客户端提供服务
        while (true) {
            //先构造一个空的DatagramPacket数据报包对象 使用receive(接收)填充
            DatagramPacket requestPacket = new DatagramPacket(new byte[4090], 4090);
            socket.receive(requestPacket);
            //DatagramPacket 是一个特殊的对象不方便直接处理,把数据拿出来构成一个字符串处理
            String request = new String(requestPacket.getData(), 0, requestPacket.getLength());
            //根据请求计算响应
            String response = process(request);
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,
                    requestPacket.getSocketAddress());
            //send(发送)的参数也是DatagramPaket,所以根据返回的相应构造 responsePacket对象
            socket.send(responsePacket);
            //打印这次请求的结果
            System.out.printf("[%s : %d] request : %s , response : %s\n",responsePacket.getAddress().toString(),
                    responsePacket.getPort(),request,response);
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        //端口号范围(1024 -> 65535)
        UdpEchoServer udpEchoServer = new UdpEchoServer(9090);
        udpEchoServer.start();

    }

}

UDP版本的回显客户端

1.从控制台读取要接收的数据

2.将请求发送到服务器

3.接收服务器的响应

4.打印解析的响应

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

public class UdpEchoClient {
    private DatagramSocket socket = null;
    private String serverIp = null;
    private int serverPort = 0;
    //客户端知道服务器的地址和Ip 才能正确的通信
    public UdpEchoClient(String serverIp, int serverPort) throws SocketException {
        socket = new DatagramSocket();
        this.serverIp = serverIp;
        this.serverPort = serverPort;
    }
    public void start() throws IOException {
        System.out.println("客户端启动");
        Scanner in = new Scanner(System.in);
        while (true) {
            System.out.println("> ");
            String request = in.next();
            if(request.contains("exit")) {
                System.out.println("退出");
                break;
            }
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIp),serverPort);//此处的ip是一个字符串,需要的是一个32位的整数使用  
              // InetAddress.getByName()方法进行转换
            socket.send(requestPacket);
            DatagramPacket responsePacket = new DatagramPacket(new byte[4090],4090);
            socket.receive(responsePacket);
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.println(response);

        }

    }

    public static void main(String[] args) throws IOException {
        UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
        client.start();
    }
}

3.TCP流套接字编程

TCP版本的回显服务器

1.读取请求

2.根据请求计算响应

3.返回响应结果

import com.sun.imageio.plugins.wbmp.WBMPImageReader;
import jdk.internal.util.xml.impl.Input;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoServer {
    private ServerSocket serverSocket = null;
    public TcpEchoServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("启动服务器");
        ExecutorService ThreadPool = Executors.newCachedThreadPool();
        while (true) {
            //使用这个clientSocket根具体的客户端进行交流 
            Socket clientSocket = serverSocket.accept();
            //使用线性池进行处理防止频繁申请释放线程
            ThreadPool.submit(() -> {
                processConnection(clientSocket);
            });
        }
    }

    private void processConnection(Socket clientSocket) {
        System.out.printf("%s : %d 客户端上线\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());
        //TCP协议针对字节流
        try (InputStream inputStream = clientSocket.getInputStream();
             OutputStream outputStream = clientSocket.getOutputStream()) {
            while (true) {
                //读取请求
                Scanner scanner = new Scanner(inputStream);
                if (!scanner.hasNext()) {
                    System.out.printf("%s : %d 客户端下线\n",clientSocket.getInetAddress().toString(),
                            clientSocket.getPort());
                    break;
                }
                //next 读到换行符/空格/其他空白符结束,并且结果不包含空白符
                String request = scanner.next();
                //根据请求计算响应
                String response = process(request);
                //OutputStream 没有写 Sting 的功能
                //可以使用字符流转换一下
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(response);
                //刷新缓冲区,保证写入
                printWriter.flush();
                System.out.printf("[%s : %d] req: %s res: %s\n",clientSocket.getInetAddress().toString(),clientSocket.getPort(),
                        request, response);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                clientSocket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    private String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoServer tcpEchoServer = new TcpEchoServer(7878);
        tcpEchoServer.start();
    }


}

TCP版本的回显客户端

1.从键盘读取用户输入的内容

2.把读取的内容构造成请求,发送给服务器

3.读取服务器的响应

4.打印响应的内容

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

public class TcpEchoClient {
    private Socket socket = null;
    public TcpEchoClient(String serverIp, int serverPort) throws IOException {
        // new 这个对象的同时, 就会进行 TCP 连接操作
        socket = new Socket(serverIp, serverPort);
    }
    public void start() {
        System.out.println("启动客户端");
        Scanner scanner = new Scanner(System.in);
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()) {
            while (true) {
                System.out.println("> ");
                String request = scanner.next();
                if (request.contains("exit")) {
                    System.out.println("goodbye");
                    break;
                }
                PrintWriter printWriter = new PrintWriter(outputStream);
                printWriter.println(request);
                printWriter.flush();
                Scanner responscanner = new Scanner(inputStream);
                String response = responscanner.next();
                System.out.println(response);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) throws IOException {
        TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",7878);
        tcpEchoClient.start();
    }

}

启动服务器和客户端

结果显示

网络编程_System_02

网络编程_java_03


标签:java,String,编程,request,网络,System,import,new
From: https://blog.51cto.com/u_16166203/7112736

相关文章

  • 网络编程day02--FTP协议
    封装socket网络通信模块-network原因:TCP、UDP客户端、服务端的操作流程固定,所以为了后期使用方便,把socket网络通信封装成网络模块任务:生成libnw.so共享库笔试、面试问题:回答原始函数讲项目:聊封装过程FTP协议FTP的独特的优势同时也是与其它客户服务器程序最大的不同点就在于......
  • 网络编程day01--socket套接字
    进程间通信-socket套接字基本特征:socket是一种接口技术,被抽象了一种文件操作,可以让同一计算机中的不同进程之间通信,也可以让不同计算机中的进程之间通信(网络通信)本地进程间通信编程模型:进程A                                        ......
  • 封装socket网络通信模块
    封装socket网络通信模块-network由于TCP、UDP客户端、服务端的操作流程固定,所以为了后期使用方便,把socket网络通信封装成网络模块并生成libnw.so共享库头文件network.h#ifndefNETWORK_H#defineNETWORK_H#include<netinet/in.h>#include<stdbool.h>#include<stdint.h>......
  • 【深度挖掘Java并发编程底层源码】「底层技术原理体系」带你零基础认识和分析学习相关
    FutureTask的基本介绍FutureTask是Java中的一个类,它实现了Future接口和Runnable接口,并且被用作线程执行的任务。FutureTask可以在多线程环境下异步执行一个任务并获取其结果。FutureTask的特点用法异步执行:通过将耗时的任务交给FutureTask,在一个单独的线程中执行,当前线程可以继续执......
  • 多线程&异步编程
    多线程&网络编程(异步编程)1)重要性,高并发,短时间内遇到大量请求2)难度硬件.操作系统多线程本身的复杂性,死锁,资源抢占,线程同步...--->多线程进程:一般指程序中运行的程序,实际作用是为程序在执行过程中创建好所需要的环境和资源.线程:是进程的一个实体,是Cpu用来调度......
  • 探索编程世界的宝藏:程序员必掌握的20大算法
    #程序员必须掌握哪些算法?#文章目录1引言2冒泡排序算法:编程世界的排序魔法3选择排序算法:排序世界的精确挑选器4插入排序算法:排序世界的巧妙插珠者5快速排序算法:排序世界的分而治之大师6归并排序算法:排序世界的合而为一大师7堆排序算法:排序世界的二叉堆巨匠8计数排序算法:排......
  • 七大常用编程范式!看看你知道几个?
    一、编程范式是什么?编程范式是程序设计的一种基本方法和规范,它代表了特定编程语言的独特风格和方法。作为一种策略,编程范式帮助程序员解决各种计算问题,其选择可以优化代码的可读性、可维护性和可扩展性。常见的编程范式包括面向对象、函数式和逻辑式等,每种范式都有其独特的理念和......
  • go语言:并发编程
    引言在C/C++中,高并发场景一般使用多线程支持;而go语言天然支持高并发。go语言采用goroutine来支持高并发场景,goroutine有官方实现的用户态的超级“线程池”,每个协程4-5KB栈内存占用并且实现机制大幅减少创建和销毁开销是go语言高并发的根本原因。OS线程(操作系统线程)一般都有固定......
  • Docker 网络和资源控制
    Docker网络保证容器提供服务,确保网络的通信。资源控制确保宿主机不被容器抢占所有资源。目录一、Docker网络实现原理二、Docker的网络模式三、CPU资源控制四、总结     一、Docker网络实现原理1.Docker网络实现原理(1)Docker使用Linux桥接,......
  • 用 GPT-4 给开源项目 GoPool 重构测试代码 - 每天5分钟玩转 GPT 编程系列(8)
    目录1.好险,差点被喷2.重构测试代码2.1引入Ginkgo测试框架2.2尝试改造旧的测试用例2.3重构功能测试代码3.总结1.好险,差点被喷早几天发了一篇文章:《仅三天,我用GPT-4生成了性能全网第一的GolangWorkerPool,轻松打败GitHub万星项目》,这标题是挺容易被怼,哇咔咔;不过最......