当前位置: 首页 > news >正文

TCP回显服务器

   TCP 是有连接,可靠传输,面相字节流,全双工。

    这里有有连接的是抽象的"连接”主要表达的是通信双方是否保存有对端的信息,如果有则是有连接的,反之则是无连接的。

   可靠传输:此处谈到的可靠并不是百分之百可靠能达到对方而是尽可能,相对来说不可靠就是完全不考虑是否能够到达对方。

   面向字节流:面向字节流就是TCP传输数据的方式,同文件流/水流是一样的特点,我们可以选择具体传多少,可以一次根据我们的要求传输N个字节。

   全双工:一个通信线路既能发送数据也可以接收数据(双向通信)。

  TCP中的 socket api 核心类有两个1) ServerSocket(专门给服务器使用的socket对象)2)         Socket(既个客户端使用,也会给服务器使用)。

  通过上述我们可以得知TCP是面相字节流,因此上传数据的基本单位是Byte。

 我们在此处进了解简单的,在这里使用的关于ServerSocket的构造方法和方法。

 

Socket的方法和构造方法:

 

 

  

  下面我们开始构建服务器:

 

public class severEsocket {private ServerSocket socket = null;public severEsocket(int port) throws IOException {socket = new ServerSocket(port);}public void start() throws IOException {System.out.println("启动服务器");while(true){//通过这种方式可以解决多个客户端可以使用连接一个服务器的问题Socket  Clintsocket = socket.accept();Thread thread = new Thread(()->{try {procession(Clintsocket);} catch (IOException e) {throw new RuntimeException(e);}});thread.start();}}private void procession(Socket clintsocket) throws IOException {try(InputStream inputStream = clintsocket.getInputStream();OutputStream outputStream = clintsocket.getOutputStream()){PrintStream printStream = new PrintStream(outputStream);Scanner scanner = new Scanner(inputStream);while(true){if(!scanner.hasNext()) {break;}String requst = scanner.next();String response = process(requst);printStream.println(requst);printStream.flush();System.out.printf("[%s:%d]\n", clintsocket.getInetAddress(), clintsocket.getPort());}}catch(IOException e){e.printStackTrace();}finally{//通过这种方式避免产生文件资源泄露针对文件描述符表System.out.printf("[%s:%d] 服务器下线\n", clintsocket.getInetAddress(), clintsocket.getPort());clintsocket.close();}}private String process(String requst) {return requst;}
}

   在构造方法中我们要在ServerSocket对象中输入端口号,只要这个构造方法成功了,那么一旦客户端启动且有相同端口号就会连接成功(一个端口号只能连接一个进程,但是一个进程可以连接多个端口号)。

Socket  Clintsocket = socket.accept();

   这里的accept()方法是接收来自客户端传送的需求,这个方法有一个特殊的作用就是如果客户端一直没有传递需求那么这个方法就会在此一直阻塞,就像如同阻塞队列一样死脑筋,如果没有需求我就一直等,直至需求到来或者进程结束。

clintsocket.close();

   这里的close()方法的使用是为了避免是文件描述符妙表空间不足导致文件资源泄露,由于文件资源泄露是有一定的延后性的所以一旦有文件资源泄露问题,那么很有可能是大问题,造成不小的损失。

  服务器的构建的步骤大体分为以下几步:

/ 获取到 socket 中持有的流对象

1. 读取请求并解析

 2. 根据请求计算响应

 3. 把响应写回给客户端

  由于我们这里是回显服务器所以我们这里的响应即使字符串客户端所输入的请求。

客户端:

public class Clint {private Socket socket = null;public Clint(String IP,int port) throws IOException {socket = new Socket(IP,port);}public void start(){System.out.println("客户端启动");try(InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()){PrintStream printStream = new PrintStream(outputStream);Scanner scannerinput = new Scanner(inputStream);Scanner scanner = new Scanner(System.in);while(true){System.out.println("请输入->");String requst = scanner.next();printStream.println(requst);printStream.flush();if(!scannerinput.hasNext()){break;}String response = scannerinput.next() ;System.out.println(response);}}catch(IOException e){e.printStackTrace();}}
}

    在这里我们是服务器的回应是返回一个字符串。

   TCP客户端的构建相较于服务器就跟家简洁了, 

printStream.flush();

  客户端和服务器中的flush()方法都是为了解决printStream中的缓冲区问题,因为像这样的IO类型的类都是自带缓冲区的,这个缓冲区会将我们所发送来的请求进行累积,他并不会使我们没输入一个他就返回一个,而是达到一个量的时候在进行返回,因此我们使用flush()来解决这种方法,当然我们也可以使用OutputStream自带的方法进行回应。

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • docker安装redis单机部署的redis.conf配置
  • 形态学处理方法
  • C++11中的Lambda表达式
  • os.path库学习之split函数
  • 【设计模式】六大基本原则
  • 前端已经学会vue,做粒子效果
  • MyBatis Plus 会在执行 SQL 查询时自动应用拦截器链,包括分页拦截器,从而简化分页逻辑的处理
  • C语言常用的字符串函数(含模拟实现)
  • 【书生大模型实战营(暑假场)】基础任务一 书生大模型全链路开源体系
  • vue中post请求返回二进制流文件下载
  • (回溯) LeetCode 131. 分割回文串
  • 【Linux进程篇】进程终章:POSIX信号量线程池线程安全的单例模式自旋锁读者写者问题
  • 图像的特征提取
  • 树莓派4/5:运行Yolov5n模型(文末附镜像文件)
  • LVS实验——部署DR模式集群
  • 分享一款快速APP功能测试工具
  • 【vuex入门系列02】mutation接收单个参数和多个参数
  • android高仿小视频、应用锁、3种存储库、QQ小红点动画、仿支付宝图表等源码...
  • CSS 三角实现
  • Mysql5.6主从复制
  • passportjs 源码分析
  • Redis学习笔记 - pipline(流水线、管道)
  • Spring Cloud中负载均衡器概览
  • SpringBoot 实战 (三) | 配置文件详解
  • Twitter赢在开放,三年创造奇迹
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue 2.3、2.4 知识点小结
  • 阿里云Kubernetes容器服务上体验Knative
  • 代理模式
  • 官方解决所有 npm 全局安装权限问题
  • 计算机在识别图像时“看到”了什么?
  • 技术攻略】php设计模式(一):简介及创建型模式
  • 力扣(LeetCode)965
  • 扑朔迷离的属性和特性【彻底弄清】
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 使用 QuickBI 搭建酷炫可视化分析
  • 网络应用优化——时延与带宽
  • 一道面试题引发的“血案”
  • 移动端唤起键盘时取消position:fixed定位
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​Z时代时尚SUV新宠:起亚赛图斯值不值得年轻人买?
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # Spring Cloud Alibaba Nacos_配置中心与服务发现(四)
  • # 安徽锐锋科技IDMS系统简介
  • # 飞书APP集成平台-数字化落地
  • #ifdef 的技巧用法
  • (1)bark-ml
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (poj1.2.1)1970(筛选法模拟)
  • (二十九)STL map容器(映射)与STL pair容器(值对)
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (回溯) LeetCode 78. 子集
  • (收藏)Git和Repo扫盲——如何取得Android源代码