TCP/IP 网络编程 第七章:优雅地断开套接字连接

这篇具有很好参考价值的文章主要介绍了TCP/IP 网络编程 第七章:优雅地断开套接字连接。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

基于TCP的半关闭

在前面的章节中,我们都是通过close或者closesocket来断开套接字连接的,但是调用这两个函数导致我们套接字完全断开,套接字将无法接受数据,并且也只能传输完最后余留在缓冲区的数据内容。此时"只关闭一部分数据交换中使用的流"的方法应运而生。

针对优雅断开的shutdown函数

#include<sys/socket.h>
int shutdown(int sock,int howto);//成功时返回0,失败时返回-1
    sock    //需要半断开的文件描述符、
    howto   //进行半断开的方式

此函数的第二个参数可能是下面之一:

1.SHUT_RD//断开输入流

2.SHUT_WR//断开输出流

3.SHUT_RDWR//同时断开IO流

为何需要半关闭

试想一个场景,在客户端和服务端建立连接后,服务端向客户端传递文件,当服务端传递完文件后,客户端需要发送一个"Thank you"给服务端。这里就有一个问题,客户端该何时知道它应该发送“Thank you”给服务端。如果服务端通过close关闭套接字发EOF给客户端的话,服务端将再也无法接受“Thank you”。因此如果服务端只用关闭它的输出流,并且传递EOF给客户端的话就能够解决这个问题。shutdown函数的半关闭可以同时做到上述的两个需求。

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

下面介绍服务器的代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<arpa/inet.h>
#include<sys/socket.h>

#defind BUF_SIZE 30;
void error_handling(char*message);

int main(int argc,char *argv[]){
    int serv_sd,clnt_sd;
    FILE *fp;
    char buf[BUF_SIZE];
    int read_cnt;

    struct sockaddr_in serv_addr,clnt_addr;
    socklen_t clnt_addr_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_addr,0,sizeof(serv_addr));
    serv_addr.sin_familiy=AF_INET;
    serv_addr.sin_addr.s_addr=htonl(INADDR_ANY);
    serv_addr.sin_port=htons(atoi(argv[1]));

    bind(serv_sd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));
    listen(serv_sd,5);

    clnt_addr_sz=sizeof(clnt_addr);
    clnt_sd=accept(serv_ad,(struct sockaddr*)&clnt_addr,&clnt_addr_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;
}

void error_handling(char *message){
    fputs(message,stderr);
    fputc('\n',stderr);
    exit(1);
}

下面介绍客户端代码:

#include<"与服务器头文件声明一致,故省略">
#defind BUF_SIZE 30
void error_handling(char *message);

int main(int argc,char*argv[]){
    int sd;
    FILE *fp;

    char buf[BUF_SIZE];
    int read_cnt;
    struct sockaddr_in serv_addr;
    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_addr,0,sizeof(serv_addr));
    serv_addr.sin_family=AF_INET;
    serv_addr.sin_addr.s_addr=inet_addr(argv[1]);
    serv_addr.sin_port=htons(atoi(argv[2]));

    connect(sd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));

    while((read_cnt=read(sd,buf,BUF_SIZE))!=0)
         fwrite((void*)buf,1,read_cnt,fp);

    puts("Reveived file data");
    write(sd,"Thank you",10);
    fclose(fp);
    close(sd);
    return 0;
}

void error_handling(char*message){
    //与服务器的内容一致   
}

基于Windows的实现

Windows平台同样通过调用shutdown函数完成半关闭,只是想起传递的参数名略有不同。

#include<winsock2.h>
int shutdown(SOCKET sock,int howto);//成功返回0.失败返回SOCKET_ERROR;
    sock   //要断开的套接字句柄
    howto  //断开方式的信息

上述函数的第二个参数的可能值及其含义如下:

1.SD_RECEIVE:断开输入流

2.SD_SEND:断开输出流

3.SD_BOTH:断开IO流

虽然这些常量名不同于Linux中的名称,但是其内部的值完全相同。文章来源地址https://www.toymoban.com/news/detail-582635.html

到了这里,关于TCP/IP 网络编程 第七章:优雅地断开套接字连接的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 第七章——函数(C++的编程模块)

    复习函数的基本知识 要使用C++函数,必须完成如下工作: 提供函数定义 提供函数原型 调用函数  库函数是已经定义和编译好的函数,同时可以使用标准库头文件提供其原型,因此只需要正确地调用这种函数即可。但是创建自己的函数时,必须自行处理上面提到的3个方面。

    2024年02月13日
    浏览(45)
  • C++ primer plus第七章编程练习答案

    1.编写一个程序,不断要求用户输入两个数,直到其中的一个为 0。对于每两个数,程序将使用一个南数来计算它们的调和平均数,并将结果返回给 main(),而后者将报告结果。调和平均数指的是倒数平均值的倒数,计算公式如下: 调和平均数=2.0*xy/(x + y) 2.编写一个程序,要求用

    2024年02月10日
    浏览(39)
  • 第七章 网络安全【计算机网络】

    2023-7-7 17:11:39 以下内容源自《【创作模板四】》 仅供学习交流使用 第六章 应用层【计算机网络】 计算机网络(第8版) 谢希仁 编著 7.1.1计算机网络面临的安全性威胁 被动攻击:截获 流量分析 主动攻击: 篡改 恶意程序 拒绝服务Dos 7.1.2安全的计算机网络 7.1.3数据加密模型

    2024年02月13日
    浏览(51)
  • 《计算机网络》 第七章 网络安全

    两大威胁:①被动攻击 ②主动攻击(篡改、恶意程序、拒接服务DoS) 对付被动攻击:加密技术 对付主动攻击:加密技术+ 鉴别技术 四个目标:①保密性 ②端点鉴别(身份验证) ③信息完整性 ④运行安全性(访问控制) 加密密钥和解密密钥使用相同密钥的体制 例如:DES(

    2024年02月03日
    浏览(48)
  • 第七章 MobileNetv2网络详解

    第一章 AlexNet网络详解 第二章 VGG网络详解 第三章 GoogLeNet网络详解  第四章 ResNet网络详解  第五章 ResNeXt网络详解  第六章 MobileNetv1网络详解  第七章 MobileNetv2网络详解  第八章 MobileNetv3网络详解  第九章 ShuffleNetv1网络详解  第十章 ShuffleNetv2网络详解  第十一章 EfficientNet

    2024年02月07日
    浏览(55)
  • 曲线艺术编程 coding curves 第七章 抛物线(Parabolas)

    原作:Keith Peters https://www.bit-101.com/blog/2022/11/coding-curves/ 译者:池中物王二狗(sheldon) blog: http://cnblogs.com/willian/ 源码:github: https://github.com/willian12345/coding-curves 曲线艺术编程系列第7章 我承认这一章脑暴时,再三考虑过是否要将抛物线包含进来。此篇覆盖的抛物线比起之前三章

    2024年02月08日
    浏览(42)
  • LINUX网络第七章:PXE——高效批量网络装机

    目录 部署PXE远程安装服务 1.PXE概述 2.实现过程 3.实验操作 3.1安装dhcp、vsftpd、tftp-server.x86_64、syslinux服务 3.2修改配置文件——DHCP ​编辑3.3修改配置文件——TFTP 3.4kickstart——无人值守安装 3.4.1选择程序 ​编辑3.4.2修改基础配置 ​编辑3.4.3修改安装方法  ​编辑3.4.4安装新引导

    2024年01月22日
    浏览(54)
  • 第七章 网络安全 | 计算机网络(谢希仁 第八版)

    计算机网络面临的安全威胁和一些主要问题 对称密匙密码体制和公匙密码体制 数字签名与鉴别 网络安全协议IPsec协议族和运输安全协议SSl/TSL的要点 系统安全:防火墙和入侵检测 7.1.1 计算机网络面临的安全性威胁 计算机网络上的通信面临的威胁可以分为两大类: 被动攻击(

    2024年02月07日
    浏览(48)
  • 网络基础学习(第七章):VRRP协议介绍及配置

    1.1 VRRP协议介绍 虚拟路由冗余协议(Virtual Router Redundancy Protocol,简称VRRP)是由IETF提出的解决局域网中配置静态网关出现单点失效现象的路由协议。 利用VRRP,一组路由器(同一个VLAN中的接口)协同工作,但只要一个处于Master状态,处于该状态的路由器接口承担实际数据流量的

    2024年02月03日
    浏览(49)
  • 计算机网络重点概念整理-第七章 网络安全【期末复习|考研复习】

    计算机网络复习系列文章传送门: 第一章 计算机网络概述 第二章 物理层 第三章 数据链路层 第四章 网络层 第五章 传输层 第六章 应用层 第七章 网络安全 计算机网络整理-简称缩写 给大家整理了一下计算机网络中的重点概念,以供大家期末复习和考研复习的时候使用。 参

    2024年02月07日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包