TCP通信

第二十一章 网络通信

本章节主要讲解的是TCP和UDP两种通信方式它们都有着自己的优点和缺点  这两种通讯方式不通的地方就是TCP是一对一通信  UDP是一对多的通信方式  接下来会一一讲解

TCP通信

TCP通信方式呢  主要的通讯方式是一对一的通讯方式,也有着优点和缺点  它的优点对比于UDP来说就是可靠一点  因为它的通讯方式是需要先发送消息 看看客户端是否能够接收到消息 如果没有回复消息的话 服务端  就不会发出文件 等待客户端回复消息,这个握手模式的话  就会非常可靠  以下代码进行讲解:

客户端代码:

package tcp;

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

/**
 * Socket客户端
 **/
public class SocketClient {
    public static void main(String[] args) {
        Socket s = null;
        try {
            // 与ip为127.0.0.1、端口为12345的服务端建立连接
            s = new Socket("127.0.0.1", 12345);

            // 创建输入流接收服务端发送的消息(字节流)
            InputStream is = s.getInputStream();
            // 将服务端返回的字节流转化为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 创建字符流读取缓冲区,方便每行读取
            BufferedReader br = new BufferedReader(isr);

            // 创建输出流返回消息
            OutputStream os = s.getOutputStream();
            // 创建输出流缓冲
            PrintWriter pw = new PrintWriter(os);

            // 创建发送消息的线程
            Runnable rOut = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 接收控制台输入
                        Scanner scan = new Scanner(System.in);
                        String msg = scan.nextLine();
                        // 将输入写入缓冲
                        pw.println(msg);
                        // 将缓冲内的数据推送至服务端并清空缓冲区
                        pw.flush();
                    } catch (Exception e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 创建接收消息的线程
            Runnable rIn = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 逐行读取服务端返回的消息并打印
                        String str = br.readLine();
                        System.out.println("服务端的消息:" + str);
                    } catch (IOException e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 启动两个线程
            Thread tOut = new Thread(rOut);
            Thread tIn = new Thread(rIn);
            tOut.start();
            tIn.start();
        }catch (IOException e) {
            try {
                // 释放资源
                s.close();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

服务端代码:

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

/**
 * Socket服务端
 **/
public class SocketServer {
    public static void main(String[] args) {
        ServerSocket ss = null;
        Socket s = null;
        try {
            // 创建监听端口为12345的Socket服务端
            ss = new ServerSocket(12345);
            System.out.println("服务端Socket服务已建立,等待客户端连接...");
            // 通过ss.accept()开始持续监听12345端口,当有连接时获取收到的包装成Socket的客户端对象
            s = ss.accept();
            // 获取客户端的IP地址和端口号
            String ip = s.getInetAddress().getHostAddress();
            int port = s.getPort();
            System.out.println("服务端与 " + ip + ":" + port + " 已建立连接");

            // 创建输入流接收客户端发送的消息(字节流)
            InputStream is = s.getInputStream();
            // 将客户端发送的字节流转化为字符流
            InputStreamReader isr = new InputStreamReader(is);
            // 创建字符流读取缓冲区,方便每行读取
            BufferedReader br = new BufferedReader(isr);

            // 创建输出流返回消息
            OutputStream os = s.getOutputStream();
            // 创建输出流缓冲
            PrintWriter pw = new PrintWriter(os);

            // 创建接受信息的线程
            Runnable rIn = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 逐行读取客户端发送的消息并打印
                        String str = br.readLine();
                        System.out.println("客户端的消息:" + str);
                    } catch (IOException e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 创建发送消息的线程
            Runnable rOut = () -> {
                boolean flag = true;
                while (flag) {
                    try {
                        // 接收控制台输入
                        Scanner scan = new Scanner(System.in);
                        String msg = scan.nextLine();
                        // 将输入写入缓冲
                        pw.println(msg);
                        // 将缓冲内的数据推送至客户端并清空缓冲区
                        pw.flush();
                    } catch (Exception e) {
                        flag = false;
                        e.printStackTrace();
                    }
                }
            };

            // 开启两个线程
            Thread tIn = new Thread(rIn);
            Thread tOut = new Thread(rOut);
            tIn.start();
            tOut.start();
        } catch (IOException e) {
            try {
                // 释放资源
                ss.close();
                s.close();
            } catch (Exception exception) {
                exception.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}

服务端代码图已经客户端的代码图:

 

运行结果图如下所示:

 

缺点也从而发现 TCP程序是一对一的通信而如果碰到了需要发通知给好几个的话 这样的话需要重复这些操作这样就会很麻烦  所以这里就需要使用到UDP通信 一对多来通信 下一个博客将会讲解UDP一对多通信

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

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

相关文章

QQ录屏怎么录声音,如何解决声音录制问题?

在数字化时代,qq不仅是我们日常沟通的工具,还提供了强大的录屏功能,让用户能够轻松捕捉屏幕上的精彩瞬间。然而,很多用户可能会困惑于qq录屏怎么录声音。在本文中,我们将详细介绍如何通过QQ录屏功能录制屏幕及声音&…

【C/PTA —— 15.结构体2(课外实践)】

C/PTA —— 15.结构体2&#xff08;课外实践&#xff09; 7-1 一帮一7-2 考试座位号7-3 新键表输出7-4 可怕的素质7-5 找出同龄者7-6 排队7-7 军训 7-1 一帮一 #include<stdio.h> #include<string.h>struct student {int a;char name[20]; };struct student1 {int …

JavaWeb-HTTP协议

1. 什么是HTTP协议 HTTP超文本传输协(Hyper Text transfer protocol)&#xff0c;是一种用于用于分布式、协作式和超媒体信息系统的应用层协议。它于1990年提出&#xff0c;经过十几年的使用与发展&#xff0c;得到不断地完善和扩展。HTTP 是为 Web 浏览器与 Web 服务器之间的…

新生儿出生缺陷筛查的关键注意事项

引言&#xff1a; 新生儿的出生缺陷是一个复杂而广泛的问题&#xff0c;及早的筛查和诊断对于预防和管理这些缺陷至关重要。出生缺陷可能涉及各个系统&#xff0c;包括心脏、神经、遗传等&#xff0c;因此及时而全面的筛查对新生儿的健康至关重要。本文将深入探讨新生儿出生缺…

Matlab 点云对称性检测

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 这是一个很有趣的功能,它的思路其实与ICP算法的思路有些相似: 首先,它会初始化两个旋转角度,即绕x轴旋转与绕y轴旋转,初始的过程是将点对称(镜像)过去,计算与匹配点之间的距离误差,误差最小者为最优初始值…

抖店店铺没流量?商品销售量低?原因在于这几个!

我是电商珠珠 近期&#xff0c;很多人来跟我反馈&#xff0c;说自己的店铺没有流量和曝光&#xff0c;更别提出单了。 其实&#xff0c;想要自己的店铺月销百万&#xff0c;每天要做的工作有很多&#xff0c;比如分析市场、选品上架、优化、对接达人等&#xff0c;想要自己的…

JAVA后端自学技能实操合集

JAVA后端自学技能实操 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习FastDFS使用docker安装FastDFS(linux)集成到springboot项目中 内容将会持续更新中,有需要添加什么内容可以再评论区留言,大家一起学习 FastDFS 组名&#xff1a;文件上传后所在的 st…

网站建设app开发小程序制作|企业软件定制

网站建设app开发小程序制作|企业软件定制 网站建设和软件开发是现代社会非常重要的领域&#xff0c;它们对于企业、机构和个人来说都具有非常大的意义。随着移动互联网的快速发展&#xff0c;小程序制作也逐渐成为一种非常受欢迎的方式。 在过去&#xff0c;建立一个网站需要具…

Andorid sudio 换行方法

1.遇到的问题&#xff0c;二维码内容要换行 String text "成绩&#xff1a;1000 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff…

JVM 类的加载器的基本特征和作用

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 1、作用 类加载器是 JVM 执行类加载机制的前提 ClassLoader的作用&#xff1a; ClassLoader是Java的核心组件&#xff0c;所有的Class都是由ClassLoader进行加载的&#xff0c;ClassLoader负责通过各种方式将Class信…

5V 全桥驱动芯片,1.3A 持续驱动输出电流,PWM(IN1/IN2)的输入模式,适用于摄像机等产品上,可替代LG9110S

GC9110 是一款低压 5V 全桥驱动芯片&#xff0c; 为摄像机、消费类产品、玩具和其他低压或 者电池供电的运动控制类应用提供了集成的 电机驱动解决方案。 GC9110 能提供高达 1.3A 的持续输出电 流。可以工作在 1.2~6V 的电源电压上。 GC9110 具有 PWM&#xff08;IN/IN&#xf…

1 接口测试介绍

在软件测试工作中&#xff0c;接口测试是必不可少的。接口测试一般是发生在单元测试之后&#xff0c;系统测试之前。当开发人员输出API文档后&#xff0c;测试人员就可以开始编写接口测试用例了。接口测试可以让测试人员更早的介入&#xff0c;不需要等待前后端联调完成才开始测…

学习IO的第五天

作业 &#xff1a;使用两个线程完成文件的拷贝写入&#xff0c;分线程1写入前半段&#xff0c;分线程2写入后半段&#xff0c;主线程用来回收资源 #include <head.h>void *sork(void *arg); void *sork2(void *arg);int file_copy(int start,int len) //拷贝的函数 {i…

摄像头为什么需要积分球进行校准?

摄像头均匀光源校准可以提高图像质量、消除误差因素、实现标准化测量、保证测量结果的可靠性&#xff0c;并提高生产效率。因此&#xff0c;对于需要高精度、高清晰度图像的领域&#xff0c;摄像头均匀光源校准是非常必要的。 一、为什么摄像头需要均匀光源校准&#xff1f; 提…

Javascript 函数介绍

Javascript 函数介绍 很多教程书一上来就讲解一堆语法&#xff0c;例如函数定义、函数调用什么。等读者看完了函数这一章都没搞懂什么是函数。 在讲解什么叫函数之前&#xff0c;我们先看下面一段代码&#xff1a; <!DOCTYPE html> <html xmlns"http://www.w3.…

在线工具分享SQL转ElasticSearchDSL语句

&#x1f60a; 作者&#xff1a; 瓶盖子io &#x1f496; 主页&#xff1a; 瓶盖子io-CSDN博客

腾讯云CentOS8 jenkins war安装jenkins步骤文档

腾讯云CentOS8 jenkins war安装jenkins步骤文档 一、安装jdk 1.1 上传jdk-11.0.20_linux-x64_bin.tar.gz 1.2 解压jdk安装包文件 tar -zxvf jdk*.tar.gz 1.3 在/usr/local 目录下创建java目录 cd /usr/local mkdir java 1.4 切到java目录&#xff0c;把jdk解压文件改名为jd…

智能优化算法应用:基于原子轨道搜索算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于原子轨道搜索算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于原子轨道搜索算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.原子轨道搜索算法4.实验参数设定5.算…

Python函数默认参数设置

在某些情况下&#xff0c;程序需要在定义函数时为一个或多个形参指定默认值&#xff0c;这样在调用函数时就可以省略为该形参传入参数值&#xff0c;而是直接使用该形参的默认值。 为形参指定默认值的语法格式如下&#xff1a; 形参名 默认值 从上面的语法格式可以看出&…

记录 | linux手动清理 buff/cache

linux下手动清理 buff/cache 切换到 root 权限 # 这个drop_caches文件可以设置的值分别为1、2、3 echo 1 > /proc/sys/vm/drop_caches # 表示清除pagecache echo 2 > /proc/sys/vm/drop_caches # 表示清除回收slab分配器中的对象&#xff08;包括目录项缓存和inode缓…