Windows 环境下的 Socket 编程 3 - 基于 TCP 的服务器/客户端

2023-05-16

基于 TCP 的服务器端/客户端

绝大多数 TCP 服务器端都按照如下顺序调用:
在这里插入图片描述
在 Windows 环境下,代码表示为:

	WSADATA wsaData;
    SOCKET hServSock, hClntSock;
    SOCKADDR_IN servAddr, clntAddr;
    int szClntAddr;
	
	/*Windows 环境 Socket 编程必须*/
    if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
        //错误处理
	
	/*创建套接字,使用 IPv4 协议族、面向连接的 TCP 数据传输方式,对于 IPv4 协议族,第三个参数总是为 0 */
    hServSock = socket(PF_INET, SOCK_STREAM, 0);
    if(hServSock == INVALID_SOCKET)
        //错误处理
    
    /*设置协议族的地址信息*/
    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;					//地址族设置为 IPv4
    servAddr.sin_addr.s_addr = htonl(INADDR_ANY);	//设置 IP 地址
    servAddr.sin_port = htons(atoi(argv[1]));		//设置端口号
	
	/*分配套接字地址*/
    if(bind(hServSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
        //错误处理
	
	/*等待连接请求*/
    if(listen(hServSock, 5) == SOCKET_ERROR)
        //错误处理
    
    /*受理客户端连接请求*/
    szClntAddr = sizeof(clntAddr);
    hClntSock = accept(hServSock, (SOCKADDR *)&clntAddr, &szClntAddr);
    if(hClntSock == INVALID_SOCKET)
        //错误处理
	
	/*接收数据*/
    strLen = recv(hClntSock, message, BUF_SIZE,0);
	
	/*发送数据*/
    send(hClntSock, (const char *)&calculation_result, sizeof(int), 0);
    
    closesocket(hClntSock);
    closesocket(hServSock);
    WSACleanup();

绝大多数 TCP 客户端都按照如下顺序调用:
在这里插入图片描述
在 Windows 环境下,代码表示为:

    WSADATA wsaData;
    SOCKET hClntSock;
    SOCKADDR_IN servAddr;
	
	/*Windows 环境 Socket 编程必须*/
    if(WSAStartup(MAKEWORD(2,2), &wsaData) != 0)
        //错误处理
	
	/*创建套接字,使用 IPv4 协议族、面向连接的 TCP 数据传输方式,对于 IPv4 协议族,第三个参数总是为 0 */
    hClntSock = socket(PF_INET, SOCK_STREAM, 0);
    if(hClntSock == INVALID_SOCKET)
        //错误处理
    
    /*设置协议族的地址信息*/
    memset(&servAddr, 0, sizeof(servAddr));
    servAddr.sin_family = AF_INET;
    servAddr.sin_addr.s_addr = inet_addr(argv[1]);
    servAddr.sin_port = htons(atoi(argv[2]));
	
	/*连接到服务器*/
    if(connect(hClntSock, (SOCKADDR *)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
        //错误处理
	
	/*发送数据*/
    send(hClntSock, message, strLen, 0);
    
    /*接收数据*/
    recv(hClntSock, &result, sizeof(int), 0);
    
    closesocket(hClntSock);
    WSACleanup();

基于 TCP 的服务器端-客户端函数调用关系
在这里插入图片描述
客户端只能等到服务器端调用 listen 函数后才能调用 connect 函数。

TCP 细节

TCP 套接字的数据收发无边界。服务器端即使调用 1 次 send 函数传输 40 字节的数据,客户端有可能通过 4 次 recv 函数调用每次读取 10 字节。也就是说,客户端可以缓慢的分批接收。
TCP 套接字的 I/O 是有缓冲的。send 函数调用后,数据将移至输出缓冲区;在适当的时候(不管是分别传送还是一次性传送)传向对方的输入缓冲区。 recv 函数调用后,从输入缓冲区读取数据。

  • I/O 缓冲区在每个 TCP 套接字中单独存在。
  • I/O 缓冲区在创建套接字时(调用 socket 函数)自动生成。
  • 即使关闭套接字也会继续传递输出缓冲中遗留的数据
  • 关闭套接字将丢失输入缓冲区中的数据
    TCP 不会因为缓冲溢出而丢失数据。这是因为 TCP 会控制数据流(滑动窗口)。

断开连接

TCP 中的断开连接过程比建立连接过程更重要,因为连接过程中一般不会出现大的变数,但断开过程有可能发生预想不到的情况。
使用 close 或者 closesocket 函数意味着完全断开连接。完全断开连接不仅指无法传输数据,而且也不能接收数据。

还有一种断开连接的方法是只断开一部分连接,成为半关闭。半关闭是指可以传输数据但无法接收,或者可以接收数据但无法传输。
每一个套接字建立后,都会存在 2 个流:
在这里插入图片描述
建立套接字的两台主机,都会拥有单独的输入流和输出流。使用 close 或者 closesocket 函数将同时断开这 2 个流,而半关闭只关闭其中 1 个流。

  1. shutdown 函数:关闭其中 1 个流
// 成功返回 0,失败返回 -1
int shutdown(SOCKET s,int how);

s:套接字
how:断开方式

  • SD_RECEIVE:断开输入流,套接字无法接收数据
  • SD_SEND:断开输出流,套接字无法传输数据
  • SD_BOTH:同时断开 I/O 流
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Windows 环境下的 Socket 编程 3 - 基于 TCP 的服务器/客户端 的相关文章

随机推荐

  • ROS控制crazyflie无人机(一)

    ROS控制crazyflie无人机 参考资料测试环境一 设置用户权限二 安装Crazyflie程序库和客户端三 安装crazyflie ros程序包四 遥控器控制crazyflie无人机 本篇博客记录了测试使用ros控制crazyflie无
  • echarts 黑色样式

    lt THIS EXAMPLE WAS DOWNLOADED FROM https echarts apache org examples zh editor html c 61 dataset simple1 gt lt DOCTYPE
  • 磁盘分区

    磁盘 xff1a 可以被分区成多个分区槽 xff08 partition xff09 以Windows来看 xff0c 磁盘可以被分区为 C xff1a xff0c D xff1a xff0c E xff1a 槽 C D E就是分区槽 而L
  • 【STM32】IAP下载程序分析

    IAP下载程序分析 IAP基本原理STM32启动流程程序跳转代码实现总结 IAP基本原理 要实现STM32的IAP xff08 在应用编程 xff09 xff0c 需要分别建立bootloader和app工程 这里的bootloader程序
  • vue el-date-picker 设置可选近30天且时间范围为7天

    对 el date picker 限制 xff1a 默认选择时间范围为最近一天 xff1b 设置快捷选项 xff1a 最近1天 最近3天 最近7天等 xff1b 限制只能选择今天以及今天以前30天 xff1b 选择一个时间之后 xff0c
  • MySQL索引分析

    1 索引是什么 xff1f 索引是一种能提高数据库查询效率的数据结构 它可以比作一本字典的目录 xff0c 可以帮你快速找到对应的记录 索引一般存储在磁盘的文件中 xff0c 它是占用物理空间的 正所谓水能载舟 xff0c 也能覆舟 适当的
  • 任务是如何调度(切换)的?

    学习任务的切换有助于自己理解操作系统的运行过程 并且任务的调度 xff08 切换 xff09 也是操作系统中的重要的部分 任务的切换中关键是任务控制块的控制 xff0c 将现在以及将来要运行的任务向堆栈中的存储与恢复 因为 C OS II总
  • 机器学习算法五:随机森林(Random Forest)

    集成学习 xff1a 通过构建并结合多个学习器来完成学习任务 xff1b 集成学习中主要包括boosting算法 和bagging算法 xff1b boosting算法 xff1a xff08 线性集成 xff09 关注于降低偏差 xff1
  • 怎样利用VNC远程连接LINUX桌面

    关于显示等问题都有 xff0c 比较详细 http blog csdn net zhouyunjie archive 2008 11 27 3396824 aspx 先要修改 vnc xstartup文件 bin sh Uncomment
  • VNC多用户

    1 为vnc建立用户 newuser 2 拷贝 root vnc 里的xstartup文件到用户目录 home newuser 3 修改xstartup文件 xff0c 在最后增加 xff1a gnome session amp 4 以ne
  • 【环境配置】初试使用mitmproxy搭建网络代理

    初试使用mitmproxy搭建网络代理 1 参考文章 老版本的很多功能已经不能用了 xff0c 用新的版本研究了一下 参考文章 https mitmproxy org http www freebuf com sectool 76361 h
  • 关于Keil 的快速注释功能,并为其添加快捷键

    原地址 xff1a http blog sina com cn s blog 6859cadf0101i3p4 html Keil版本uVision 4 03 1 在Keil gt Edit gt Advanced中有两项 Comment
  • 【OpenCV】ArUco Marker

    1 创建 span class token keyword import span cv2 span class token keyword as span cv span class token keyword import span n
  • 非常实用,华为、新华三、锐捷交换机的配置命令分享

    干弱电这一行难免会接触到交换机 xff0c 华为 新华三锐捷交换机又是最常见的交换机 xff0c 关于他们的命令配置很容易弄混 xff0c 而且在实际项目配置中也很容易出错 xff0c 因此 xff0c 本期我们将来介绍这三家交换机的基础配
  • 打飞机小游戏

    设计目标 xff1a 高质量的代码要有这些优点 复用性好 扩展性好 维护性好 可移植性好 健壮性好 效率好 可读性好 所以设计代码的时候不要只想到功能的实现 xff0c 还要考虑功能的扩展及代码复用等 设计规则 xff1a 需求分析抽取共性
  • windows 安装 Navicat Premiun

    Navicat Premiun 中文网站 Navicat Premiun 官网下载 简介 Navicat Premium 是一套数据库管理工具 xff0c 结合其它Navicat 成员 xff0c 支持单一程序同时连接到 MySQL Mar
  • 论文排版中MathType的使用(论文投稿必备)

    使用mathtype往论文中插入公式时 xff0c 若需要编号 xff0c 则点击 右编号 xff08 若只需插入文本行内 xff0c 则点 内联 xff09 由于论文是分栏格式 xff0c 单行公式太长导致编号串行 xff0c 因此需要将
  • python语言中变量的共享引用及原处修改

    代码段一 xff1a 代码段1 gt gt gt a 61 6 gt gt gt b 61 a gt gt gt a b 输出 xff1a 6 6 上述代码段一中 xff0c 第一行我们创建了对象6 xff0c 并将变量a 与之相关联 xf
  • 通用环形缓冲区 LwRB 使用指南

    什么是 LwRB xff1f LwRB 是一个开源 通用环形缓冲区库 xff0c 为嵌入式系统进行了优化 源码点击这里 Github LwRB 特性 使用 ANSI C99 编写FIFO xff08 先进先出 xff09 无动态内存分配 x
  • Windows 环境下的 Socket 编程 3 - 基于 TCP 的服务器/客户端

    基于 TCP 的服务器端 客户端 绝大多数 TCP 服务器端都按照如下顺序调用 xff1a 在 Windows 环境下 xff0c 代码表示为 xff1a WSADATA wsaData span class token punctuati