我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java网络编程 - TCP通信

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java网络编程 - TCP通信

TCP通信

快速入门(一发一收)

TCP协议回顾:

TCP是一种面向连接,安全、可靠的传输数据的协议

传输前,采用“三次握手”方式,点对点通信,是可靠的

在连接中可进行大数据量的传输

TCP通信模式:

在这里插入图片描述

在java中只要是使用java.net.Socket类实现通信,底层即是使用了TCP协议

编写客户端代码

Socket(客户端):

构造器说明
Socket(String host , int port)创建发送端的Socket对象与服务端连接,参数为服务端程序的ip和端口。

Socket类成员方法:

方法说明
OutputStream getOutputStream()获得字节输出流对象
InputStream getInputStream()获得字节输入流对象

客户端实现步骤:

  • 创建客户端的Socket对象,请求与服务端的连接。
  • 使用socket对象调用getOutputStream()方法得到字节输出流。
  • 使用字节输出流完成数据的发送。
  • 不建议直接关闭socket管道释放资源, 一般用户退出时才会关闭。
public class ClientDemo {    public static void main(String[] args) {        try {            // 1. 创建socket通信管道请求与服务端进行连接                        Socket socket = new Socket("127.0.0.1", 7777);            // 2. 从socket通信管道中获取到字节输出流            OutputStream os = socket.getOutputStream();            // 包裹低级字节输出流为字节打印流            PrintStream ps = new PrintStream(os);            // 3. 打印流发送消息            ps.println("我是TCP的客户端");            ps.flush(); // 刷新        } catch (Exception e) {            e.printStackTrace();        }    }}

编写服务器代码

ServerSocket(服务端):

构造器说明
ServerSocket(int port)注册服务端端口

ServerSocket类成员方法:

方法说明
Socket accept()等待接收客户端的Socket通信连接
连接成功返回Socket对象与客户端建立端到端通信

服务端实现步骤:

  • 创建ServerSocket对象,注册服务端端口。
  • 调用ServerSocket对象的accept()方法,等待客户端的连接,并得到Socket管道对象。
  • 通过Socket对象调用getInputStream()方法得到字节输入流、完成数据的接收。
  • 不建议直接关闭socket管道释放资源, 一般用户退出时才会关闭。
public class ServerDemo {    public static void main(String[] args) {        try {            // 1. 创建ServerSocket对象注册服务器端口            ServerSocket serverSocket = new ServerSocket(7777);            // 2. 调用accept方法, 等待客户端连接, 连接成功返回socket管道对象            Socket socket = serverSocket.accept();            // 3. 从socket管道中获取字节输入流, 完成数据接受            InputStream is = socket.getInputStream();            // 把字节输入流包装为缓冲字符输入流进行消息接收            BufferedReader br = new BufferedReader(new InputStreamReader(is));            // 按照行读取            String message;            if ((message = br.readLine()) != null) {                System.out.println(message);            }        } catch (Exception e) {            e.printStackTrace();        }    }}

多发多收

需求

  • 使用TCP通信方式实现:多发多收消息。

具体要求

  • 可以使用死循环控制服务端收完消息继续等待接收下一个消息。
  • 客户端也可以使用死循环等待用户不断输入消息。
  • 客户端一旦输入了exit,则关闭客户端程序,并释放资源。

客户端

public class ClientDemo {    public static void main(String[] args) {        try {            Socket socket = new Socket("127.0.0.1", 7777);            OutputStream os = socket.getOutputStream();            PrintStream ps = new PrintStream(os);            // 客户端使用死循环等待用户不断地输入消息            Scanner scanner = new Scanner(System.in);            while (true) {                System.out.println("发送消息: ");                String inp = scanner.nextLine();                // 一旦输入了exit,则关闭客户端程序,并释放资源                if (inp.equals("exit")) {                    System.out.println("下线成功");                    ps.close();                    break;                }                ps.println(inp);                ps.flush();            }        } catch (Exception e) {            e.printStackTrace();        }    }}

服务端

public class ServerDemo {    public static void main(String[] args) {        try {            ServerSocket serverSocket = new ServerSocket(7777);            Socket socket = serverSocket.accept();            InputStream is = socket.getInputStream();            BufferedReader br = new BufferedReader(new InputStreamReader(is));            String message;            // 死循环控制服务端收完消息继续等待接收下一个消息            while ((message = br.readLine()) != null) {                System.out.println("收到消息: " + message);            }        } catch (Exception e) {            e.printStackTrace();        }    }}

多发多收(同时接受多个客户端)

思考: 案例实现了多发多收,那么是否可以同时接收多个客户端的消息?

不可以的。

因为服务端现在只有一个线程,只能与一个客户端进行通信; 并且上面代码中, 我们只连接了一个客户端然后就在死循环接受消息。

那么如何才可以让服务端可以处理多个客户端的通信需求

引入多线程。

同时处理多个客户端消息实现架构如下:

主线程死循环不断地接收socket链接, 每成功链接一个socket, 就交给子线程处理

在这里插入图片描述

实现步骤如下:

优化服务器代码即可

创建一个线程类, 用来处理接收消息

public class ServerReaderThread extends Thread {    private Socket socket;    public ServerReaderThread(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        try {            InputStream is = socket.getInputStream();            BufferedReader br = new BufferedReader(new InputStreamReader(is));            String message;            // 死循环控制服务端收完消息继续等待接收下一个消息            while ((message = br.readLine()) != null) {                System.out.println("收到消息: " + message);            }        } catch (Exception e) {            e.printStackTrace();        }    }}

在服务器主线程中, 每链接到一个socket都要创建一个线程类交给子线程处理

public class ServerDemo {    public static void main(String[] args) {        try {            ServerSocket serverSocket = new ServerSocket(7777);            // 1. 主线程中定义一个死循环由主线程不断地接收客户端socket管道连接            while (true) {                // 2. 每接收到一个socket管道, 都交给一个独立的子线程负责读取消息                Socket socket = serverSocket.accept();                // 交给子线程处理, 并启动子线程                new ServerReaderThread(socket).start();            }        } catch (Exception e) {            e.printStackTrace();        }    }}

线程池优化

目前的通信架构存在什么问题

客户端与服务端的线程模型是: 1-1的关系, 有多少客户端就会创建多少线程。

客户端并发越多,系统瘫痪的越快。

引入线程池处理多个客户端消息的架构如下:

在这里插入图片描述

线程池优化多发多收, 我们只需要优化服务器的代码即可:

创建一个Runnable任务类

public class ServerReaderRunnable implements Runnable {    private Socket socket;    public ServerReaderRunnable(Socket socket) {        this.socket = socket;    }    @Override    public void run() {        try {            InputStream is = socket.getInputStream();            BufferedReader br = new BufferedReader(new InputStreamReader(is));            String message;            // 死循环控制服务端收完消息继续等待接收下一个消息            while ((message = br.readLine()) != null) {                System.out.println(socket.getRemoteSocketAddress() + "收到消息: " + message);            }        } catch (Exception e) {            e.printStackTrace();        }    }}

优化服务器端代码

public class ServerDemo {    // 使用静态变量记录一个线程池对象    private static ExecutorService pool = new ThreadPoolExecutor(3, 5, 6,            TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), Executors.defaultThreadFactory(),            new ThreadPoolExecutor.AbortPolicy());    public static void main(String[] args) {        try {            ServerSocket serverSocket = new ServerSocket(7777);            while (true) {                Socket socket = serverSocket.accept();                System.out.println(socket.getRemoteSocketAddress() + "上线了");                // 创建Runnable任务交给线程池处理                pool.execute(new ServerReaderRunnable(socket));            }        } catch (Exception e) {            e.printStackTrace();        }    }}

线程池优势是什么?

服务端可以复用线程处理多个客户端,可以避免系统瘫痪。

适合客户端通信时长较短的场景。
计思想, 客户端将消息发送给服务器, 再由服务器进行转发给其他客户端。

来源地址:https://blog.csdn.net/m0_71485750/article/details/127720523

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Java网络编程 - TCP通信

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Java网络编程 - TCP通信

文章目录 TCP通信快速入门(一发一收)编写客户端代码编写服务器代码 多发多收多发多收(同时接受多个客户端)线程池优化 TCP通信 快速入门(一发一收) TCP协议回顾: TCP是一种面向连接,安全、可靠的
2023-08-16

Java网络编程之TCP通信完整代码示例

一、概述  Socket类是Java执行客户端TCP操作的基础类,这个类本身使用代码通过主机操作系统的本地TCP栈进行通信。Socket类的方法会建立和销毁连接,设置各种Socket选项。  ServerSocket类是Java执行服务器端
2023-05-30

Java网络编程 - UDP通信

文章目录 UDP通信快速入门一发一收多发多收广播组播 UDP通信 快速入门 UDP协议的特点: UDP是一种无连接、不可靠传输的协议。 将数据源IP、目的地IP和端口以及数据封装成数据包,大小限制在64KB内,直
2023-08-30

网络编程—tcp

一、TCP简介          二、tcp网络程序-客户端          三、tcp网络程序-服务器          四、案例:文件下载器          五、tcp三次握手、四次挥手          六、tcp长连接和短连接 
2023-01-31

python 网络通信协议/TCP,UD

一.osi七层协议互联网协议按照功能不同分为osi七层或tcp/ip五层或tcp/ip四层协议具体内容 各层的功能简述: 【1】物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等。它的主要作用是传
2023-01-30

如何使用Java进行网络通信编程?(在Java中,应如何编写网络通信程序?)

Java提供强大的网络通信功能,可用于编写健壮的网络应用程序。通过使用TCP/IP套接字,您可以创建客户端端和服务器端程序,并通过数据流进行通信。数据序列化允许传输复杂对象,而高级功能(如多线程和NIO)可提高性能并简化编程。本指南详细介绍了如何在Java中进行网络通信编程,包括服务器端和客户端端示例,以及高级功能的概述。
如何使用Java进行网络通信编程?(在Java中,应如何编写网络通信程序?)
2024-04-02

Python socket网络编程TCP/IP服务器与客户端通信

Python socket网络编程 初学 python,前段时间买了两本书《python 编程从入门到实践》《Python 核心编程第三版》,第一本书主要讲的是一些基本语法和一些基本的使用方法,而第二本则深入很多,自己看来也是一知半解,刚好
2022-06-04

Java网络编程TCP如何实现聊天功能

这篇文章主要为大家展示了“Java网络编程TCP如何实现聊天功能”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Java网络编程TCP如何实现聊天功能”这篇文章吧。客户端:package com.
2023-06-20

python网络-Socket之TCP编

一、TCP简介1、TCP介绍TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP通信需要经过创建连接、数据传送、终止连接三个
2023-01-31

第二十七天- 网络通信协议 TCP UD

1.网络通信协议  osi七层模型:按照分工不同把互联网协议从逻辑上划分了层级    socket层 2.理解socket:  Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一
2023-01-30

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录