《TCP/IP网络编程》阅读笔记--基于 TCP 的半关闭

目录

1--基于TCP的半关闭

1-1--TCP单方面完全断开的问题

1-2--shutdown()函数

1-3--半关闭的必要性

2--基于半关闭的文件传输程序


1--基于TCP的半关闭

1-1--TCP单方面完全断开的问题

        Linux 系统中的 close 函数会将 TCP Socket 的连接完全断开,这意味着不能收发数据(关闭了输入流和输出流),这可能会导致主机 A 无法收到主机 B 的数据(主机A的输入流被关闭了); 

1-2--shutdown()函数

#include <sys/socket.h>
int shutdown(int sock, int howto);
// 成功时返回 0, 失败时返回 -1
// sock 表示需要断开的 Socket 的文件描述符
// howto 表示传递断开的方式信息

        shutdown() 函数可以避免上面完全关闭导致数据丢失的问题,其通过指定断开的方式来选择性地断开输入流、输出流

        断开的方式通过第二个参数来指定,其中 SHUT_RD 表示断开输入流SHUT_WR 表示断开输出流SHUT_RDWR 表示同时断开 I/O 流

1-3--半关闭的必要性

        对于服务器端/客户端的数据传输问题,传输文件的服务器端只需连续传输文件数据即可,但客户端无法知道何时结束数据的接收;

        为了解决上述问题,服务器端应向客户端传递一个 EOF 表示文件传输结束,而客户端通过接收到 EOF 知晓文件传递结束,可以停止接收数据

        断开输出流可以向外传递 EOF(无论是设置 SHUT_WR 还是直接使用 close() 函数);

2--基于半关闭的文件传输程序

服务器端:

// gcc file_server.c -o file_server
// ./file_server 9190#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char *argv[]){int serv_sd, clnt_sd;FILE* fp;char buf[BUF_SIZE];int read_cnt;struct sockaddr_in serv_adr, clnt_adr;socklen_t clnt_adr_sz;if(argc != 2){printf("Usage : %s <port>\n", argv[0]);exit(1);}fp = fopen("file_server.c", "rb");serv_sd = socket(PF_INET, SOCK_STREAM, 0);memset(&serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = htonl(INADDR_ANY);serv_adr.sin_port = htons(atoi(argv[1]));bind(serv_sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));listen(serv_sd, 5);clnt_adr_sz = sizeof(clnt_adr);clnt_sd = accept(serv_sd, (struct sockaddr*)&clnt_adr, &clnt_adr_sz);while(1){read_cnt = fread((void*)buf, 1, BUF_SIZE, fp);if(read_cnt < BUF_SIZE){write(clnt_sd, buf, read_cnt);break;}write(clnt_sd, buf, BUF_SIZE);}shutdown(clnt_sd, SHUT_WR);read(clnt_sd, buf, BUF_SIZE);printf("Message from client: %s \n", buf);fclose(fp);close(clnt_sd);close(serv_sd);return 0;}

客户端:

// gcc file_client.c -o file_client
// ./file_client 127.0.0.1 9190#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>#define BUF_SIZE 30void error_handling(char *message){fputs(message, stderr);fputc('\n', stderr);exit(1);
}int main(int argc, char *argv[]){int sd;FILE* fp;char buf[BUF_SIZE];int read_cnt;struct sockaddr_in serv_adr;if(argc != 3){printf("Usage : %s <IP> <port>\n", argv[0]);exit(1);}fp = fopen("receive.dat", "wb");sd = socket(PF_INET, SOCK_STREAM, 0);memset(&serv_adr, 0, sizeof(serv_adr));serv_adr.sin_family = AF_INET;serv_adr.sin_addr.s_addr = inet_addr(argv[1]);serv_adr.sin_port = htons(atoi(argv[2]));connect(sd, (struct sockaddr*)&serv_adr, sizeof(serv_adr));while((read_cnt = read(sd, buf, BUF_SIZE)) != 0){fwrite((void*)buf, 1, read_cnt, fp);}puts("Received file data");write(sd, "Thank you", 10);fclose(fp);close(sd);return 0;
}

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

el-table自适应列宽实现

【背景小记】 el-table的el-table-column如果不指定width的话&#xff0c;会自动设定一个宽度&#xff0c;表格内容会自动换行&#xff0c;对强迫症用户来说非常不友好&#xff0c;为了追求完美用户体验&#xff0c;所以这里需要实现两个效果&#xff1a; 1. 强制表格内容不换…

CAS策略

CAS CAS&#xff08;Compare And Swap&#xff09;比较并交换 CAS是多线程环境下对共享变量进行修改时的一种策略&#xff0c;主要存在三个参数&#xff1a;当前值、预估值、结果 CAS采用的策略是当一个线程要对共享变量进行修改时&#xff0c;需要获取内存中共享变量的值作…

小白备战大厂算法笔试(二)——数组、链表、列表

文章目录 常见数据结构数组初始化访问元素插入元素删除元素遍历数组查找元素扩容数组关于数组 链表初始化插入节点删除节点访问节点查找节点常见类型典型应用 数组VS链表列表初始化访问元素插入与删除元素遍历列表拼接列表排序列表简单实现 常见数据结构 常见的数据结构包括数…

工业4.0时代下,到底什么是智慧工厂?

关键词&#xff1a;智慧工厂、智慧工厂数字化、设备设施数字化、能源管理系统、动环监控、智能运维、数据采集、工业互联网 随着物联网、大数据和移动应用等新一轮信息技术的发展&#xff0c;全球化工业革命开始提上日程&#xff0c;工业转型开始进入实质阶段。作为工业4.0的最…

自动化测试面试常见技术题目

1&#xff1a;一行代码实现1--100之和 print(sum(list(range(1,101)))) 2&#xff1a;如何在一个函数内部修改全局变量 global  修改全局变量 局部作用域只能调用全局作用域的变量&#xff0c;但是不熊修改全局作用域的变量&#xff0c;如果想要修改全局作用域的变量需要gl…

【算法】插入排序

插入排序 插入排序代码实现代码优化 排序&#xff1a; 排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。 稳定性&#xff1a; 假定在待排序的记录序列中&#xff0c;存在多个具有相同的关键字的记录&…

一文讲解Linux内核内存管理架构

内存管理子系统可能是linux内核中最为复杂的一个子系统&#xff0c;其支持的功能需求众多&#xff0c;如页面映射、页面分配、页面回收、页面交换、冷热页面、紧急页面、页面碎片管理、页面缓存、页面统计等&#xff0c;而且对性能也有很高的要求。本文从内存管理硬件架构、地址…

RabbitMQ高级特性

目录 消息的可靠投递confirm和return Consumer Ack 消费端限流 TTL Time To Live&#xff08;存活时间/过期时间&#xff09; 死信队列&#xff08;死信交换机&#xff09; 延迟队列 日志与监控 rabbitmqctl管理和监控 消息追踪 消息的可靠投递confirm和return 持久…

小程序隐私保护授权处理方式之弹窗组件

欢迎点击关注-前端面试进阶指南&#xff1a;前端登顶之巅-最全面的前端知识点梳理总结 *分享一个使用比较久的&#x1fa9c; 小程序隐私保护授权弹窗组件 调用wx.getUserProfile进行授权时&#xff0c;返回错误信息&#xff1a;{errMsg: “getUserProfile:fail api scope is…

李宏毅-21-hw3:对11种食物进行分类-CNN

一、代码慢慢阅读理解总结内化&#xff1a; 1.关于torch.nn.covd2d()的参数含义、具体用法、功能&#xff1a; &#xff08;1&#xff09;参数含义&#xff1a; 注意&#xff0c;里面的“padding”参数&#xff1a;《both》side所以是上下左右《四》边都会加一个padding数量…

jmeter 数据库连接配置 JDBC Connection Configuration

jmeter 从数据库获取变量信息 官方文档参考&#xff1a; [jmeter安装路径]/printable_docs/usermanual/component_reference.html#JDBC_Connection_Configuration 引入数据库连接&#xff1a; 将MySQLjar包存放至jemter指定目录&#xff08;/apache-jmeter-3.3/lib&#xff09…

K8S的CKA考试环境和题目

CKA考试这几年来虽然版本在升级&#xff0c;但题目一直没有大的变化&#xff0c;通过K8S考试的方法就是在模拟环境上反复练习&#xff0c;通过练习熟悉考试环境和考试过程中可能遇到的坑。这里姚远老师详细向大家介绍一下考试的环境和题目&#xff0c;需要详细资料的同学请在文…

pdf怎么转换成jpg图片?

随着数字文档的广泛应用&#xff0c;将PDF转换为JPG图片格式成为了一个常见的需求。无论是为了在网页上展示内容&#xff0c;还是为了与他人分享图片&#xff0c;以下是一些简单的方法&#xff0c;帮助您将PDF文件快速转换为高质量的JPG图片。 方法一&#xff1a;在线PDF转JPG…

B-Tree 索引和 Hash 索引的对比

分析&回答 B-Tree 索引的特点 B-tree 索引可以用于使用 , >, >, <, < 或者 BETWEEN 运算符的列比较。如果 LIKE 的参数是一个没有以通配符起始的常量字符串的话也可以使用这种索引。 有时&#xff0c;即使有索引可以使用&#xff0c;MySQL 也不使用任何索引。…

大数据之MapReduce

MapReduce概述 是一个分布式的编程框架&#xff0c;MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序&#xff0c;并发运行在一个Hadoop集群上。 优点&#xff1a; 易于编程&#xff0c;简单的实现一些接口&#xff0c;就可以完成一…

C高级 DAY1

一、复习 命令行提示符 ubuntuubuntu:~$ 第一个ubuntu:用户名 第二个ubuntu:主机名 &#xff1a; ---> 分割符 ~ &#xff1a; 用户的家目录 $: 普通用户 #&#xff1a;管理员 切换用户 su 用户名---》切换至指定用户 su --》切换至超级用户 sudo 加在…

excel表格怎么换行?好用的3个方法

excel是一款功能齐全的电子表格应用程序&#xff0c;广泛用于数据分析、记录和管理。在创建excel表格时&#xff0c;有时候我们需要在单元格中输入较长的文本内容&#xff0c;这时如何进行换行是一个常见问题。本文将为您介绍excel表格怎么换行的3种方法&#xff0c;帮助您轻松…

LeetCode 3. 无重复字符的最长子串

题目链接 题目解析 我们需要找的是含重复元素的最长子串&#xff0c;当然直接暴力求解固然简单。但是可能引发的情况是超时&#xff0c;而且面试官想看到的也不是让你去暴力解决这类问题。因此我们使用哈希滑动窗口的思想来解决。 滑动窗口哈希 使用哈希表的缘故是更好的判…

Vue + Element UI 实现权限管理系统 前端篇(四):优化登录流程

完善登录流程 1. 丰富登录界面 1.1 从 Element 指南中选择组件模板丰富登录界面&#xff0c;放置一个登录界面表单&#xff0c;包含账号密码输入框和登录重置按钮。 <template><el-form :model"loginForm" :rules"fieldRules" ref"loginFo…

ORB-SLAM2算法14之局部建图线程Local Mapping

文章目录 0 引言1 概述2 处理队列中的关键帧3 剔除坏的地图点4 创建新地图点5 融合当前关键帧和其共视帧的地图点6 局部BA优化7 剔除冗余关键帧 0 引言 ORB-SLAM2算法7详细了解了System主类和多线程、ORB-SLAM2学习笔记8详细了解了图像特征点提取和描述子的生成、ORB-SLAM2算法…