【java查漏补缺】网络编程

news2024/11/29 22:13:13

网络编程实际上就是通过套接字进行连接后进行通信,本质还是程序进行IO操作。

所谓套接字,实际上就是IP地址加上端口号的组合,通过套接字,可以连接到网络中某一台计算机的某一个进程。

下面就是客户端和服务器的简单例子,这个简单的例子中,服务器只能和一个客户端进行通信,并且当客户端连接结束后,客户端和服务器同时停止。

  • 简单的客户端服务器模型

我们首先来看一下服务器的代码,服务器的执行一共有五个步骤

  1. 实例化一个ServerSocket对象

  2. 使用Socket对象接收ServerSocket示例执行accept()方法的返回值,该方法会一直被被阻塞,建立socket连接

  3. 和客户端进行通信

  4. 关闭Socket连接

  5. 关闭ServerSocket连接

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

public class ServerDemo {
    public static final int PORT = 8005;

    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Started:" + s);
        try{
            Socket socket = s.accept();
            try{
                System.out.println("Connection accepted: " + socket);
                BufferedReader in =
                        new BufferedReader(
                                new InputStreamReader(socket.getInputStream()));
                PrintWriter out =
                        new PrintWriter(
                                new BufferedWriter(
                                        new OutputStreamWriter(socket.getOutputStream())));
                while(true){
                    String str = in.readLine();
                    System.out.println("Echoing: " + str);
                    if(str.equals("END")) break;
                    out.println("Receiving: " + str);
                    out.flush();
                }
            } finally {
                System.out.println("closing...");
                socket.close();
            }

        } finally {
            s.close();
        }
    }

}

客户端连接相对来说比较简单,连接步骤有三个

  1. 建立Socket连接,其中需要传入两个参数,分别是服务器的IP地址和端口号

  2. 和服务器进行通信

  3. 关闭Socket连接

 

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

public class ClientDemo {

    public static void main(String[] args) throws IOException {
        InetAddress addr = InetAddress.getByName("127.0.0.1");
        System.out.println("addr=" + addr);
        Socket socket = new Socket(addr, ServerDemo.PORT);
        try{
            System.out.println("socket=" + socket);
            BufferedReader in =
                    new BufferedReader(new InputStreamReader(System.in));
            BufferedReader serverIn =
                    new BufferedReader(new InputStreamReader(socket.getInputStream()));
            PrintWriter out =
                    new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
            while(true){
                String line = in.readLine();
                out.println(line);
                out.flush();
                String serverInfo = serverIn.readLine();
                if(serverInfo != null){
                    System.out.println(serverInfo);
                }
                if(line.equals("END")) break;
            }
        } finally {
            System.out.println("closing...");
            socket.close();
        }
    }

}

上述例子中ServerDemo是服务器类,ClientDemo是客户端类,连接建立后,客户端可以给服务器发送消息,知道服务器收到"END"字符串的时候停止服务。

 

  • 可以服务多个客户端的服务器模型

上述的服务器模型只能对一个客户端进行连接,当连接断开之后,服务器程序也会停止。当然,一个好用的服务器需要随时随刻都能服务尽可能多的客户端,我们只需要对上述代码稍加修改,就能实现一个功能稍微复杂的服务器模型。

可以服务多个客户端的服务器模型的基本逻辑是,持续监听accept()方法是否有返回,一旦有返回,就接收其返回的Socket对象,并且新建立一个线程执行服务器逻辑,然后再持续监听accept()方法,重复上述步骤。

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

public class MultiServerDemo {

    public static final int PORT = 8005;

    public static void main(String[] args) throws IOException {
        ServerSocket s = new ServerSocket(PORT);
        System.out.println("Server Started");
        try {
            while(true){
                Socket socket = s.accept();
                try {
                    new ServerOneDemo(socket);
                } catch (IOException e) {
                    socket.close();
                }
            }
        } finally {
            s.close();
        }
    }
}

class ServerOneDemo extends Thread{
    private Socket socket;
    private BufferedReader in;
    private PrintWriter out;
    public ServerOneDemo(Socket s) throws IOException{
        socket = s;
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
        // 启动线程
        start();
    }
    public void run(){
        try {
            while(true){
                String str = in.readLine();
                System.out.println("Echoing: " + str);
                if(str.equals("END")) break;
                out.println("Receiving: " + str);
                out.flush();
            }
            System.out.println("closing...");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

上述代码分为两个类来编写,其中MultiServerDemo类负责监控accpet()方法的返回情况,一点有返回值就会实例化一个ServerOneDemo。ServerOneDemo类继承了Thread,实现了run()方法,在构造函数中接收一个Socket对象作为参数,并且执行start()方法自动开启线程。执行代码,可以发现,只要我们不结束程序,那么就可以一直和客户端建立连接并接收消息。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/152386.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3-ElmentPlus封装通用表格-含单元格操作-多选-分页器

Sam9029的CSDN博客主页:Sam9029的博客_CSDN博客-JS学习,CSS学习,Vue-2领域博主 **🐱‍🐉🐱‍🐉恭喜你,若此文你认为写的不错,不要吝啬你的赞扬,求收藏,求评论,求一个大大…

【测试】测试分类

努力经营当下,直至未来明朗! 文章目录测试分类(大框架)一、按照测试对象划分一)可靠性测试二)容错性测试三)安装卸载测试(万能公式中可以加上)四)内存泄漏测试…

合芯科技携手新享科技联合打造国产化项目管理系统解决方案

北京新享科技有限公司 北京新享科技有限公司,是上海合见工业软件集团控股的子公司。上海合见工业软件集团有限公司是自主创新的高性能工业软件及解决方案提供商,以EDA(电子设计自动化,Electronic Design Automation)领…

【实际开发03】- dto + vo - 先处理 dto , 后处理 vo ( 通常少一注解 )

目录 0. 建议 : 多用组合 , 少用继承 1. EqualsAndHashCode(callSuper true) - 解决允许调用父类 2. 序列化 ID : private static final long serialVersionUID 1L; 1. serialVersionUID 作用 : 序列化时为了保持版本的兼容性 3. 数据概览 ( 统计 ) : XxxxProfileVO 1.…

CAD常用命令:对象选择过滤器(FILTER)

CAD软件中为了方便绘图,有效地提升绘图效率,提供了很多CAD命令快捷键,而CAD对象选择过滤器作为CAD常见命令之一,在日常的CAD绘图过程中经常能用到,你知道CAD对象选择过滤器怎么用吗?本文小编就来给大家分享…

Qt解析Json数据

目录前言1.下载 jsoncpp 源码2.编译3.JSON数据读写示例4.jsoncpp核心类详解前言 本文主要介绍了使用Qt框架编程时如何解析JSON数据的一种方法。JSON是英文JavaScript Object Notation 的缩写,它是一种轻量级的数据交换格式,具有方便阅读和编写的优点&am…

Jenkins 项目的 gpg: signing failed: Bad passphrase 错误

因为我们项目需要使用 Jenkins 对文件进行签名。但是我们遇到了gpg: signing failed: Bad passphrase错误。原因和解决通常这个问题的原因是 Key 已经配置成功并且已经被命令行找到了。主要原因是你的秘钥密码配置的问题。这个配置有 2 个地方,第一个地方是项目的 P…

2022年度牛奶乳品行业数据:十大热门品牌销量排行榜

当前,随着经济的发展及人民生活水平的提高,牛奶乳品已经日趋成为人们在日常饮食中不可缺少的食物之一,市面上的产品种类也越来越多。并且,随着人们消费习惯的转变,牛奶乳品的消费场景也日益多元化。未来,预…

jdk1.8之函数式接口

l[TOC] 函数式接口概述 jdk1.8 引入了一个核心概念:函数式接口(Functional Interface)。如果一个接口有且只有一个未实现的方法,那这个接口就称为函数式接口。并且引入了一个新的注解:FunctionalInterface &#xff0…

一、Gradle入门

文章目录一、Gradle入门1.1 Gradle 简介1.2 常见的项目构建工具1.3 Gradle 安装1.3.1 Gradle 安装说明1.3.2 安装 JDK1.3.3 下载并解压到指定目录1.3.4 配置环境变量1.3.5 检测是否安装成功1.4 Gradle 项目目录结构1.5 Gradle 创建第一个项目1.5.1 Gradle 中的常用命令1.5.2 修…

【MySQL进阶教程】视图/存储过程/触发器

前言 本文为 【MySQL进阶教程】视图/存储过程/触发器 相关知识,下边将对视图,存储过程,存储函数,触发器等进行详尽介绍~ 📌博主主页:小新要变强 的主页 👉Java全栈学习路线可参考:【…

MySQL高级【存储函数触发器】

1:存储函数1.1:介绍存储函数是有返回值的存储过程,存储函数的参数只能是IN类型的。具体语法如下: CREATE FUNCTION 存储函数名称 ([ 参数列表 ]) RETURNS type [characteristic ...] BEGIN -- SQL语句 RETURN ...; END ;character…

如何管理存量用户?

存量市场的老客户对于企业来说如同一座金矿,好好运营老客户,可以给企业带来源源不断的新客户,企业所获得的收益远比拉新所获收益要高的多。 前言 存量客户是指某个时间段里原先已有的客户,与新增客户相对应,通俗点说&…

Python开发Web扫描器实战

今天继续给大家介绍渗透测试相关知识,本文主要内容是Python开发Web扫描器实战。 免责声明: 本文所介绍的内容仅做学习交流使用,严禁利用文中技术进行非法行为,否则造成一切严重后果自负! 再次强调:严禁对未…

机器学习--模型评估、过拟合和欠拟合、模型验证

目录 一、模型评估 模型指标 常见关于分类的指标 准确率 精确率(精确度) 召回率 F1 score PR曲线: ROC AUC 二、过拟合和欠拟合 训练与泛化误差的区别 什么样的情况会导致欠拟合与过拟合? 模型的复杂度(能够拟合各种各样函…

分组加密模式 ECB CBC OFB CFB

多个分组加密互相之间如何关联 ECB模式 每个分组之间单独加密,互不关联 2个分组明文一样,结果也一样,那么只需爆破其中1个就可以了 每个分组互不关联,可以分段同时来爆破,不安全 可以通过替换某段密文来达到替换明…

11.Isaac教程--在docker中模拟训练姿势估计模型

在docker中模拟训练姿势估计模型 文章目录在docker中模拟训练姿势估计模型怎么运行的主机设置硬件要求软件要求NGC Docker 注册表设置第一次运行数据集生成配置您的工作区Jupyter 变量设置开始训练添加您自己的 3D 模型故障排除接下来物体检测和 3D 姿态估计在机器人技术中起着…

『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格

『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格 文章目录『精』EditorConfig 小老鼠 跨编辑器 | IDE 保持一致的编码风格一、什么是EditorConfig二、文件识别符三、风格属性控制四、不同规则参考1)、简洁通用2)、前端Vue项目3)、前端React项目4)、前端Angular项…

Linux常用命令——nm命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) nm 显示二进制目标文件的符号表 补充说明 nm命令被用于显示二进制目标文件的符号表。 语法 nm(选项)(参数)选项 -A:每个符号前显示文件名; -D:显示动态符号; …

成员变量-java循环机构

1.概念所谓的成员变量,是指在类中(不是方法或其他代码块)直接定义的变量。根据是否带有static关键字,成员变量又分为静态变量(类变量)、实例变量(对象变量)。成员变量在整个类的内部都有效,可以在当前类的任何方法中使用。另外如果成员变量不…