[TCP协议]基于TCP协议的字典服务器

目录

1.TCP协议简介:

2.TCP协议在Java中封装的类以及方法

3.字典服务器

3.1服务器代码:

3.2客户端代码:


1.TCP协议简介:

TCP协议是一种有连接,面向字节流,全双工,可靠的网络通信协议.它相对于UDP协议来说有以下几点好处:

1.它是可靠传输,相比于UDP协议,传输的数据更加可靠.当然这里的可靠是相对的,并不是真的万无一失.我们会在后面的博客中给大家详细介绍TCP协议的可靠传输.

2.它传输的字节流文件没有大小限制,不像UDP协议,一次只能传输64kb的报文数据.

但是也有缺点:

1.开销大,需要对连接的建立与维护,以及确认数据报的确认和重传,会增加网络开销.

2 传输效率低;由于可靠性和流量控制,会对传输效率造成一定的影响

基于这些特性:因此TCP协议不适用于实时性要求高的程序,适合数据库访问,网络游览器,文件传输,电子邮件等应用.

2.TCP协议在Java中封装的类以及方法

TCP协议在Java中有两个api,分别是SeverSocket和Socket

顾名思义,SeverSocket是给服务器用的api,它仅限于服务器使用,而Socket服务器和客户端都可以使用.

SeverSocket构造方法:

方法签名方法说明
ServerSocket(int port)创建一个服务端流套接字Socket,并绑定到指定端口

SeverSocket的方法:

法签
方法说明
Socket
accept()
开始监听指定端口(创建时绑定的端口),有客户端连接后,返回一个服务端Socket
对象,并基于该Socket建立与客户端的连接,否则阻塞等待
void
close()
关闭此套接字

Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。
不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据的。

Socket的构造方法:

方法签名方法说明
Socket(String host, int
port)
创建一个客户端流套接字Socket,并与对应IP的主机上,对应端口的
进程建立连接

Socket的方法:

方法签名方法说明
InetAddress getInetAddress()返回套接字所连接的地址
InputStream getInputStream()返回此套接字的输入流
OutputStream getOutputStream()返回此套接字的输出流

3.字典服务器

下面我们基于这两个api做一个简单的字典服务器.它类似于翻译软件,当我们去输入中文字符的时候,会返回并且打印与之对应的英文字符.

为了更方便大家理解,我们先做一个在之前的文章提过的回显服务器:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TcpEchoSever {
    ServerSocket serverSocket = null;
    public TcpEchoSever(int port) throws IOException { //指定服务器的端口号
        serverSocket = new ServerSocket(port);
    }
    public void strat() throws IOException {
        System.out.println("服务器启动");
        while (true){
            Socket socket = serverSocket.accept(); //通过acccept方法获取到我们的客户端信息并保存到socket中
            Thread t = new Thread(()->{  //这里使用多线程是为了让不同的客户端都分配一个线程,以免因为一个客户端让它阻塞而别的客户端不能访问
                try {
                    accress(socket);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });
            t.start();

        }
    }

    public void accress(Socket socket) throws IOException {
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()) { //字节流,有点类似于文件操作
            System.out.printf("[客户端连接%s:%d]\n",socket.getInetAddress(),socket.getPort());
            while (true) {
                {   Scanner inputScnner = new Scanner(inputStream);
                    if (!inputScnner.hasNext()) {
                        System.out.println("连接中断");
                        break;
                    }
                    String request = inputScnner.next(); //读取数据
                    String reqonse = func(request); //把数据进行服务器端的计算请求
                    PrintWriter writer  = new PrintWriter(outputStream);//将响应返回给客户端
                    writer.println(reqonse);
                    writer.flush();//这里的flush是为了把缓冲池里的数据给刷新
                    System.out.printf("[%s:%d]\n,request : %s ,reqonse : %s"
                    ,socket.getInetAddress(),socket.getPort(),request,reqonse);//打印日志
                }
            }
        }finally {
            socket.close();//防止客户端过多,造成文件资源泄露,让文件描述符表满了
        }
    }
    public String func(String request){
        return request;
    }

    public static void main(String[] args) throws IOException {
        TcpEchoSever tcpEchoSever = new TcpEchoSever(9090);
        tcpEchoSever.strat();
    }
}

我们直接继承这个服务器代码,并且重写func方法,将我们的字典加入进去

3.1服务器代码:

import java.io.IOException;
import java.util.HashMap;

public class TcpDcarySever extends TcpEchoSever{
    HashMap<String,String> hashMap = new HashMap<>();

    public TcpDcarySever(int port) throws IOException {
        super(port);
        hashMap.put("小狗","dog");
        hashMap.put("小猫","cat");
        hashMap.put("小坤","chincken");
    }
    @Override
    public String func(String request) {
        return hashMap.getOrDefault(request,"没找到,请重新查找");
    } //重写func方法
    public static void main(String[] args) throws IOException {
        TcpDcarySever tcpDcarySever = new TcpDcarySever(9091);
        tcpDcarySever.strat();
    }
}

3.2客户端代码:

步骤都在注释里

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 {
    Socket socket = null;
    public TcpEchoClient(String SeverIp,int port) throws IOException { //体现了TCP协议的有连接 得在构造方法中把目的服务器的IP地址和端口号指定
        socket = new Socket(SeverIp , port);
    }
    private void start(){
        System.out.println("客户端启动");
        try (InputStream inputStream = socket.getInputStream();
             OutputStream outputStream = socket.getOutputStream()){ //一样是面向字节流 ,所以和文件操作类似
            Scanner scanner = new Scanner(System.in);
            Scanner inpuscnner = new Scanner(inputStream);
            PrintWriter writer = new PrintWriter(outputStream); 
            while (true){
                if(!scanner.hasNext()){
                    break;
                }
                String requeset = scanner.next();//从控制台读取数据
                writer.println(requeset);//发送请求
                writer.flush();//刷新缓冲池
                String reqonse = inpuscnner.next();//从服务器端拿到请求并构造成字符串
                System.out.println(reqonse);
            }

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

    public static void main(String[] args) throws IOException {
        TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1",9091);//指定目标的IP地址和端口号
        tcpEchoClient.start();
    }
}

结果演示:

启动服务器:

启动客户端观察服务器的情况:

输入中文字符看看:

此时客户端是这样的

为了观察多线程的作用,我们再次启动另一个客户端:

可以看到另一个客户端也脸上了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

两个近期的计算机领域国际学术会议(软件工程、计算机安全):欢迎投稿

近期&#xff0c;受邀担任两个国际学术会议的Special session共同主席及程序委员会成员&#xff08;TPC member&#xff09;&#xff0c;欢迎广大学界同行踊跃投稿&#xff0c;分享最新研究成果。期待这个夏天能够在夏威夷檀香山或者加利福尼亚圣荷西与各位学者深入交流。 SERA…

深度学习-搭建Colab环境

Google Colab(Colaboratory) 是一个免费的云端环境&#xff0c;旨在帮助开发者和研究人员轻松进行机器学习和数据科学工作。它提供了许多优势&#xff0c;使得编写、执行和共享代码变得更加简单和高效。Colab 在云端提供了预配置的环境&#xff0c;可以直接开始编写代码&#x…

React中使用LazyBuilder实现页面懒加载方法二

前言&#xff1a; 在一个表格中&#xff0c;需要展示100条数据&#xff0c;当每条数据里面需要承载的内容很多&#xff0c;需要渲染的元素也很多的时候&#xff0c;容易造成页面加载的速度很慢&#xff0c;不能给用户提供很好的体验时&#xff0c;懒加载是优化页面加载速度的方…

【网络协议测试】畸形数据包——圣诞树攻击(DOS攻击)

简介 TCP所有标志位被设置为1的数据包被称为圣诞树数据包&#xff08;XMas Tree packet&#xff09;&#xff0c;之所以叫这个名是因为这些标志位就像圣诞树上灯一样全部被点亮。 标志位介绍 TCP报文格式&#xff1a; 控制标志&#xff08;Control Bits&#xff09;共6个bi…

【虚拟机数据恢复】异常断电导致虚拟机无法启动的数据恢复案例

虚拟机数据恢复环境&#xff1a; 某品牌R710服务器MD3200存储&#xff0c;上层是ESXI虚拟机和虚拟机文件&#xff0c;虚拟机中存放有SQL Server数据库。 虚拟机故障&#xff1a; 机房非正常断电导致虚拟机无法启动。服务器管理员检查后发现虚拟机配置文件丢失&#xff0c;所幸…

JPDA框架和JDWP协议

前言 在逆向开发中,一般都需要对目标App进行代码注入。主流的代码注入工具是Frida,这个工具能稳定高效实现java代码hook和native代码hook,不过缺点是需要使用Root设备,而且用js开发,入门门槛较高。最近发现一种非Root环境下对Debug App进行代码注入的方案,原理是利用Jav…

Unity MonoBehaviour 生成dll

dllllllllllllll&#x1f953; &#x1f959;vs创建类库项目&#x1f9c0;添加UnityEngine、UnityEditor引用&#x1f355;添加MonoBehaviour类&#x1f9aa;设置dll生成路径&#x1f37f;生成dll&#x1f354;使用dll中的Mono类 &#x1f959;vs创建类库项目 &#x1f9c0;添加…

qiankun子应用静态资源404问题有效解决(涉及 css文件引用图片、svg图片无法转换成 base64等问题)

在&#x1f449;&#x1f3fb; qiankun微前端部署&#x1f448;&#x1f3fb;这个部署方式的前提下&#xff0c;遇到的问题并解决问题的过程 最开始的问题现象 通过http请求本地的静态json文件404css中部分引入的图片无法显示 最开始的解决方式 在&#x1f449;&#x1f3…

YOLO系列(YOLO1-YOLO5)技术规格、应用场景、特点及性能对比分析

文章目录 前言一、YOLOv1-YOLOv5技术规格对比&#xff1a;二、主要应用场景和特点&#xff1a;三、性能对比分析&#xff1a;四、市场应用前景及对不同用户群体的潜在影响&#xff1a;总结 前言 YOLO&#xff08;You Only Look Once&#xff09;系列模型作为一种实时目标检测算…

OpenAI 降低价格并修复拒绝工作的“懒惰”GPT-4,另外ChatGPT 新增了两个小功能

OpenAI降低了GPT-3.5 Turbo模型的API访问价格&#xff0c;输入和输出价格分别降低了50%和25%。这对于使用API进行文本密集型应用程序的用户来说是一个好消息。 OpenAI官网&#xff1a;OpenAI AIGC专区&#xff1a;aigc 教程专区&#xff1a;AI绘画&#xff0c;AI视频&#x…

npm,cnpm install报:Error: certificate has expired at TLSSocket.onConnectSecure

问题描述 最近发现前端项目 CI/CD 时失败&#xff0c;报下面的错误。npm淘宝镜像源证书过期导致的。 [npminstall:get] retry GET https://registry.npm.taobao.org/vue-router after 400ms, retry left 1, error: ResponseError: certificate has expired, GET https://reg…

【Unity小技巧】一个脚本实现控制3D远程/近战敌人AI

最终效果 文章目录 最终效果烘培导航地图配置敌人导航数据简单配置敌人动画敌人AI脚本完结 想了解导航的其他内容可以看我这篇文章&#xff1a;【Unity游戏开发教程】零基础带你从小白到超神29——导航系统 烘培导航地图 选中地面&#xff0c;设置为静态导航 点击烘培&#xf…

《动手学深度学习(PyTorch版)》笔记4.4

注&#xff1a;书中对代码的讲解并不详细&#xff0c;本文对很多细节做了详细注释。另外&#xff0c;书上的源代码是在Jupyter Notebook上运行的&#xff0c;较为分散&#xff0c;本文将代码集中起来&#xff0c;并加以完善&#xff0c;全部用vscode在python 3.9.18下测试通过。…

写静态页面——魅族声学_前端页面练习

1、效果: 1、html代码: <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>魅族声学</titl…

5G时代下的融合CDN新风口

近年来&#xff0c;随着网络技术的飞速发展&#xff0c;互联网流量视频化的趋势日益明显&#xff0c;视频应用使互联网的可扩展性、可演进性、服务质量和网络安全面临诸多挑战。为克服传统IP网络在服务视频应用当中的不足&#xff0c;内容分发网络CDN被提出&#xff0c;并迅速成…

java servlet运输公司管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 java Web运输公司管理系统是一套完善的java web信息管理系统 serlvetdaobean mvc 模式开发 &#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主 要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5…

Go的单元测试

开发项目过程中&#xff0c;少不了单元测试&#xff1b;下面我们认识下单元测试&#xff1a; Go 语言测试框架可以让我们很容易地进行单元测试&#xff0c;但是需要遵循五点规则。 含有单元测试代码的 go 文件必须以 _test.go 结尾&#xff0c;Go 语言测试工具只认符合这个规…

2. MySQL 多实例

重点&#xff1a; MySQL 的 三种安装方式&#xff1a;包安装&#xff0c;二进制安装&#xff0c;源码编译安装。 MySQL 的 基本使用 MySQL 多实例 DDLcreate alter drop DML insert update delete DQL select 2.5&#xff09;通用 二进制格式安装 MySQL 2.5.1&#xff…

JavaScript学习-原型和原型链

原型和原型链 示例代码 //创建一个Person类 class Person {constructor(name) {this.name name;}drink() {console.log(喝水);} } //创建一个Teacher类&#xff0c;继承Person class Teacher extends Person {constructor(name, subject) {super(name);this.subject subjec…

微信小程序 仿微信聊天界面

1. 需求效果图 2. 方案 为实现这样的效果&#xff0c;首先要解决两个问题&#xff1a; 2.1.点击输入框弹出软键盘后&#xff0c;将已有的少许聊天内容弹出&#xff0c;导致看不到的问题 点击输入框弹出软键盘后&#xff0c;将已有的少许聊天内容弹出&#xff0c;导致看不到的问…
最新文章