【网络编程】TCP Socket编程

TCP Socket编程

  • 1. ServerSocket
  • 2. Socket
  • 3. TCP的长短连接
  • 4. Socket 通信模型
  • 5. 代码示例:TCP 回显服务器

流套接字: 使用传输层TCP协议
TCP: 即Transmission Control Protocol(传输控制协议),传输层协议。
TCP的特点:

  1. 有连接
  2. 可靠传输
  3. 面向字节流
  4. 有接收缓冲区,也有发送缓冲区
  5. 大小不限

1. ServerSocket

ServerSocket 是创建TCP服务端Socket的API。

注意: ServerSocket 只能用于 服务器端。

构造方法:

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

方法:

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

2. Socket

Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服务端Socket。

构造方法:

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

注意:这里面的 host 和 port 是要连接的服务器的 IP 地址和端口号。

方法:

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

3. TCP的长短连接

TCP发送数据时,需要先建立连接,什么时候关闭连接就决定是短连接还是长连接:

短连接: 每次接收到数据并返回响应后,都关闭连接,即是短连接。也就是说,短连接只能一次收数据。
长连接: 不关闭连接,一直保持连接状态,双方不停的收发数据,即是长连接。也就是说,长连接可以多次收发数据。

两者区别如下:

  1. 建立连接、关闭连接的耗时:短连接每次请求、响应都需要建立连接,关闭连接;而长连接只需要第一次建立连接,之后的请求、响应都可以直接传输。相对来说建立连接,关闭连接也是要耗时的,长连接效率更高。
  2. 主动发送请求不同:短连接一般是客户端主动向服务端发送请求;而长连接可以是客户端主动发送请求,也可以是服务端主动发。
  3. 两者的使用场景有不同:短连接适用于客户端请求频率不高的场景,如浏览网页等。长连接适用于客户端与服务端通信频繁的场景,如聊天室,实时游戏等。

4. Socket 通信模型

在这里插入图片描述

5. 代码示例:TCP 回显服务器

服务器代码:

class TcpEchoServer {public ServerSocket serverSocket;//专门用来接受请求并建立链接public Socket clientSocket;//专门用来处理请求public TcpEchoServer(int port) throws IOException {this.serverSocket=new ServerSocket(port);}public void start() throws IOException {System.out.println("服务器启动!");//也可以利用线程池ExecutorService threadsPool= Executors.newCachedThreadPool();while(true){//接受请求clientSocket=serverSocket.accept();
//            //利用多线程才能让服务器同时处理多个客户端的请求
//            Thread t=new Thread(()->{
//                //建立链接并处理请求
//                try {
//                    createConnection(clientSocket);
//                } catch (IOException e) {
//                    throw new RuntimeException(e);
//                }
//            });
//            t.start();//创建线程池相对于每次创建一个线程来说效率更高一些threadsPool.submit(()->{try {createConnection(clientSocket);} catch (IOException e) {throw new RuntimeException(e);}});}}public void createConnection(Socket clientSocket) throws IOException {System.out.printf("[%s:%d]建立链接成功\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());//三个步骤//1.读取客户端请求(根据打开的文件流确定了读取的是客户端发来的请求)//这里针对TCP的读写和对于文件的读写是一摸一样的//利用socket构造文件流try(InputStream inputStream=clientSocket.getInputStream()){//注意打开的流//直接利用scanner读取(利用原生的InputStream也是可以的,但Scanner更方便)Scanner scanner=new Scanner(inputStream);try(OutputStream outputStream=clientSocket.getOutputStream()){//注意打开的流while(true){if(!scanner.hasNext()){System.out.printf("[%s:%d]断开链接\n",clientSocket.getInetAddress().toString(),clientSocket.getPort());break;}//读取请求(TCP以字符流进行传输)// 读到空白符/ 空格/换行才会停止String request=scanner.next();//2.根据请求计算响应String response=process(request);//3.返回响应(根据打开的文件流决定了是往客户端返回请求)//为了方便用PrintWriter对OutputStream进行包裹PrintWriter printWriter=new PrintWriter(outputStream);// 因为使用 next,读到空白符/ 空格/换行才会停止,所以须使用 println printWriter.println(response);printWriter.flush();System.out.printf("[%d][req:%s resp:%s]\n",clientSocket.getPort(),request,response);}}}finally {clientSocket.close();//记得及时关闭}}public String process(String request){return request;}public static void main(String[] args) throws IOException {TcpEchoServer tcpEchoServer=new TcpEchoServer(9090);tcpEchoServer.start();}
}

客户端代码:

class TcpEchoClient {public Socket client;//TCP中客户端构造函数的ip和port指的是要链接的服务器的IP和portpublic TcpEchoClient(String serverIp, int serverPort) throws IOException {this.client = new Socket(serverIp, serverPort);}public void start() throws IOException {System.out.println("和服务器建立链接成功");Scanner scanner = new Scanner(System.in);//这里针对TCP的读写和对于文件的读写是一摸一样的//利用socket构造文件流try (InputStream inputStream = client.getInputStream()) {try (OutputStream outputStream = client.getOutputStream()) {//接收从控制台输入的字符串while (true) {System.out.println("->");String request = scanner.next();//构造请求并发送请求(PrintWriter和Scanner对应)//注意文件流PrintWriter printWriter = new PrintWriter(outputStream);// 因为使用 next,读到空白符/ 空格/换行才会停止,所以须使用 println printWriter.println(request);printWriter.flush();//如果不及时刷新,服务器可能不能及时接收到数据//接收响应Scanner respScanner = new Scanner(inputStream);String response = respScanner.next();//显示到控制台上System.out.printf("[req:%s  resp:%s]\n", request, response);}}}}public static void main(String[] args) throws IOException {TcpEchoClient tcpEchoClient = new TcpEchoClient("127.0.0.1", 9090);tcpEchoClient.start();}
}

注意:当然要先启动服务器再启动客户端!

好啦! 以上就是对 TCP Socket编程的讲解,希望能帮到你 !
评论区欢迎指正 !

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

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

相关文章

【计算机网络】IP协议(下)

文章目录 1. 特殊的IP地址2. IP地址的数量限制3. 私有IP地址和公网IP地址私有IP为什么不能出现在公网上?解决方案——NAT技术的使用 4. 路由5. IP分片问题为什么要进行切片?如何做的分片和组装?16位标识3位标志13位片偏移例子 细节问题如何区…

基于springboot地方废物回收机构管理系统springboot11

大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…

智慧农业农场小程序源码 智慧农场系统源码

智慧农业农场小程序源码 智慧农场系统源码 一、 智慧农场系统的组成 智慧农场系统一般包括传感器、控制器、数据采集与处理平台、应用软件等组成部分。其中, 传感器主要用于采集土壤温度、湿度、光照强度等环境参数,以及作物生长状态、水肥情况等生产信息。控制器则根据传感器…

GLTF编辑器的另一个作用

1、GLB模型介绍 GLB(GLTF Binary)是一种用于表示三维模型和场景的文件格式。GLTF是"GL Transmission Format"的缩写,是一种开放的、跨平台的标准,旨在在各种3D图形应用程序和引擎之间进行交换和共享。 GLB文件是GLTF文件…

PyCharm 手动下载插件

插件模块一直加载失败,报错信息: Marketplace plugins are not loaded. Check the internet connection and refresh. 尝试了以下方法,均告失败: pip 换源Manage Plugin Repositories...HTTP 代理设置...关闭三个防火墙 最后选…

RK3568平台开发系列讲解(工具命令篇)ADB的安装

🚀返回专栏总目录 文章目录 一、ADB介绍二、Windows 下安装 adb 工具沉淀、分享、成长,让自己和他人都能有所收获!😄 一、ADB介绍 adb 全称 Android Debug Bridge,直译过来就是 Android 调试桥,它是一个通用的命令行工具。adb 做为 Android 设备与 PC 端连接的一个桥梁…

MissionPlanner编译过程

环境 windows 10 mission planner 1.3.80 visual studio 2022 git 2.22.0 下载源码 (已配置git和ssh) 从github上克隆源码 git clone gitgithub.com:ArduPilot/MissionPlanner.git进入根目录 cd MissionPlanner在根目录下的ExtLibs文件下是链接的其它github源码&#xff0…

MySQL 高级(进阶) SQL 语句(二) -----存储过程

目录 1 存储过程 1.1 创建存储过程​ 1.2 调用存储过程 1.3 查看存储过程 1.4 存储过程的参数 1.5 修改存储过程 1.6 删除存储过程 2 条件语句 3 循环语句 1 存储过程 存储过程是一组为了完成特定功能的SQL语句集合。 存储过程在使用过程中是将常用或者复杂的工作预…

ClickHouse分布式集群部署

目录 ​编辑 一、环境说明 二、安装部署 2.1 RPM方式安装 2.1.1 安装yum-utils 2.1.2 配置yum repo源 2.1.3 yum install 下载安装clickhouse 2.2 信息配置 2.2.1 配置外网可访问地址 2.2.2 修改存储路径 2.2.2.1 新建存储目录 2.2.2.2 授权 2.2.2.3 修改配置 2.…

单片机第三季-第三课:STM32开发板原理图、配置、浮点运算单元

目录 1,开发板原理图 2,浮点运算单元(FPU) 1,开发板原理图 课程视频比较早,介绍了三款开发板。观看视频时用的开发板说和51单片机共板的STM32核心板,将51单片机从底座拆下来后,安…

【从0学习Solidity】35. 荷兰拍卖

【从0学习Solidity】35. 荷兰拍卖 博主简介:不写代码没饭吃,一名全栈领域的创作者,专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构,分享一些项目实战经验以及前沿技术的见解。关注我们的主页,探索全栈…

黑马JVM总结(十四)

(1)分代回收_1 Java虚拟机都是结合前面几种算法,让他们协同工作,具体实现是虚拟机里面一个叫做分代的垃圾回收机制,把我们堆内存大的区域划分为两块新生代、老年代 新生代有划分为伊甸园、幸存区Form、幸存区To 为什…

ARMv8 cache的包含策略inclusive 和 exclusive之间的区别以及Cortex-A55示例详解

Inclusive 和 Exclusive 一, 什么是cache的inclusive 和 exclusive二,Inclusive 和 Exclusive cache示例2.1 Inclusive cache2.2 Exclusive cache 三, inclusive cache和 exclusive cache的比较3.1 cache coherency3.2 miss rate3.3 cache ca…

使用 Docker 安装 Elasticsearch (本地环境 M1 Mac)

Elasticsearchkibana下载安装 docker pull elasticsearch:7.16.2docker run --name es -d -e ES_JAVA_OPTS“-Xms512m -Xmx512m” -e “discovery.typesingle-node” -p 9200:9200 -p 9300:9300 elasticsearch:7.16.2docker pull kibana:7.16.2docker run --name kibana -e EL…

最频繁被问到的SQL面试题

面试感叹失败的原因可能有很多,而做成的道路只有⼀条,那就是不断积累。纯手工的8291字的SQL面试题总结分享给初学者,俗称八股文,期待对新手有所帮助。 窗口函数题 窗口函数其实就是根据当前数据, 计算其在所在的组中的统计数据。…

网工基础知识——以太网

1972年Bob Metcalfe“以太网之父”被Xerox雇佣为网络专家,Bob Metcalfe 来到Xerox公司的Palo Alto研究中心(PARC)的第一个任务是把Palo Alto的计算机连接到ARPANET(Internet的前身)上。1972年底Bob Metcalfe以ALOHA系统…

嵌入式开发笔记:STM32的外设GPIO知识学习

GPIO简介: • GPIO ( General Purpose Input Output )通用输入输出口 • 可配置为 8 种输入输出模式 • 引脚电平: 0V~3.3V ,部分引脚可容忍 5V (如舵机和驱动直流电机) • 输出模式下可控制端口…

机器学习 day35(决策树)

决策树 上图的数据集是一个特征值X采用分类值,即只取几个离散值,同时也是一个二元分类任务,即标签Y只有两个值 上图为之前数据集对应的决策树,最顶层的节点称为根节点,椭圆形节点称为决策节点,矩形节点称…

springboot整合返回数据统一封装

1、MagCode,错误码枚举类 package com.mgx.common.enums;import lombok.*; import lombok.extern.slf4j.Slf4j;/*** 错误码* author mgx*/ Slf4j NoArgsConstructor AllArgsConstructor public enum MsgCode {/*** 枚举标识,根据业务类型进行添加*/Code…

阻塞队列-生产者消费者模型

阻塞队列介绍标准库阻塞队列使用基于阻塞队列的简单生产者消费者模型。实现一个简单型阻塞队列 (基于数组实现) 阻塞队列介绍 不要和之前学多线程的就绪队列搞混; 阻塞队列:也是一个队列,先进先出。带有特殊的功能 &…