当前位置: 首页 > news >正文

Linux系统编程-DAY10(TCP操作)

一、网络模型
1、服务器/客户端模型
(1)C/S:client server

(2)B/S:browser server

(3)P2P:peer to peer

2、C/S与B/S区别
(1)客户端不同:B/S模型中B为通用客户端,C/S模型中C为专用客户端;

(2)使用协议不同:

                B/S模型:用HTTP(超文本传输协议)

                C/S模型:自定义(自由度更高)

(3)功能角度:

                B/S模型:功能设计相对简单

                C/S模型:功能设计复杂

(4)资源角度:

                B/S模型:所有资源都由服务端发过来

                C/S模型:资源可认为是本地的(事先下好的)

3、P2P模型
下载软件、文件、视频可用(既是客户端也干了服务器的事(提供服务))

二、TCP(传输控制协议)
(一)TCP概述
TCP 是 TCPIIP 体系中非常复杂的一个协议。下面介绍TCP最主要的特点。

(1)TCP是面向连接的运输层协议。

(2)每一条 TCP连接只能有两个端点(endpoint),每一条 TCP连接只能是点对点的(一对一)。

(3)TCP提供可靠交付的服务。也就是说,通过TCP连接传送的数据,无差错、不丢失、不重复、并且按序到达。

(4)TCP提供全双工通信。TCP允许通信双方的应用进程在任何时候都能发送数据。

(5)面向字节流。

注:三次握手的第一次封装在accept()函数和connect()函数中;

        四次挥手双方都调用close()函数,双方都把close()函数走完才认为四次挥手结束。

(二)TCP的特征(面问高频问题)
1、有链接
先确定链路,建立连接(在整个通信过程中一直保持,除非双方断开连接)

三次握手:建立连接;四次挥手:断开连接

 1-3三次握手(建立连接),4-7处理数据(收发),7-10四次挥手(断开连接)

第8步:ACK1022(第一种情况:之前请求的数据未发完,先应答,说明收到断开,套接字进入半连接状态;第二种情况:双方数据量没那么大,服务器没什么要发的,第八步是有可能被省略的)

SYN:请求连接

ACK:应答

编号:协商双方起始编号

2、可靠传输(因为有链接)
(1)应答机制

(2)超时重传

3、TCP流式套接字
(1)流式套接字:全双工(既能收也能发)(因为是双缓冲区(发送缓冲区和接收缓冲区))

(2)流式套接字示意图:

第一种:recv(100)一把收完(拿走)

第二种:recv(3)一个一个取,不会丢

(3)流式套接字(两个)特性:

        数据本身是连续的(无边界);

        有顺序的(数据会有序到达)(发和收的次序可不对应)

4、扩展:黏包问题
(1)(双方发数据事先未约定好)数据发送过去接收方没办法正常按发送方那边拆开包;

(2)原因:数据无边界;

(3)解决方案

        a.设计分隔符(加分隔符(自己设定))

        b.固定大小(典型代表:struct(结构体))

        c.自定义协议

eg:AA CC 04 1 2 3 4 CRC1 CRC2 BB DD

        AA CC:开头标志

        BB DD:结尾标志

        04:标识数据长度(自定义)

        1 2 3 4:正文4个字节

三、编程步骤
1.服务端:socket()---> bind()--->listen()--->accept()--->recv()--->send()--->close()
2.客户端:socket()--->connect()--->send()--->recv()--->send()

recv 的返回值 >0 :实际收到的字节数
                       =0 :断开
                       <0 :出错
调用recv会阻塞,send写满的时候会阻塞
3.conn是通信套接字

四、代码与例题
                                                        TCP ser.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>typedef struct sockaddr *(SA);
int	main(int argc, char **argv)
{int listfd = socket(AF_INET, SOCK_STREAM, 0);if(-1 == listfd){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("192.168.0.199");int ret = bind(listfd, (SA)&ser, sizeof(ser));if(-1 == ret){perror("bind");return 1;}listen(listfd, 3);socklen_t len = sizeof(cli);int conn = accept(listfd, (SA)&cli, &len);if(-1 == conn){perror("conn");return 1;}while(1){char buf[256] = {0};ret = recv(conn, buf, sizeof(buf), 0);if(ret <= 0){break;}printf("cli : %s\n", buf);time_t tm;time(&tm);struct tm *info = localtime(&tm);sprintf(buf, "%s %d:%d:%d\n",buf, info->tm_hour, info->tm_min, info->tm_sec);send(conn, buf, strlen(buf), 0);}close(conn);close(listfd);return 0;
}

                                                                TCP cli.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <time.h>
#include <sys/types.h>         
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>typedef struct sockaddr *(SA);
int	main(int argc, char **argv)
{int conn = socket(AF_INET, SOCK_STREAM, 0);if(-1 == conn){perror("socket");return 1;}struct sockaddr_in ser, cli;bzero(&ser, sizeof(ser));bzero(&cli, sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr = inet_addr("192.168.0.119");int ret = connect(conn, (SA)&ser, sizeof(ser));if(-1 == ret){perror("connect");return 1;}while(1){char buf[256] = {0};strcpy(buf, "cyy ");send(conn, buf, strlen(buf), 0);ret = recv(conn, buf, sizeof(buf), 0);if(ret <= 0){break;}printf("ser: %s", buf);fflush(stdout);sleep(1);}close(conn);return 0;
}
http://www.xdnf.cn/news/879805.html

相关文章:

  • elementUI点击浏览table所选行数据查看文档
  • linux 故障处置通用流程-36计-14-27
  • JVM 核心概念深度解析
  • CB/T 3361-2019 甲板敷料检测
  • 中小企业IT运维痛点与OMS主动运维体系解析
  • 装一台水冷主机
  • uniappx插件nutpi-idcard 开发与使用指南(适配鸿蒙)
  • Linux C学习路线全概及知识点笔记2(仅供个人参考)
  • uniapp实现的简约美观的星级评分组件
  • uniapp图片文档预览
  • PHP 8.5 即将发布:管道操作符、强力调试
  • springboot mysql/mariadb迁移成oceanbase
  • 基于Java(SpringBoot、Mybatis、SpringMvc)+MySQL实现(Web)小二结账系统
  • 【图片识别改名】如何批量将图片按图片上文字重命名?自动批量识别图片文字并命名,基于图片文字内容改名,WPF和京东ocr识别的解决方案
  • 【SSM】SpringMVC学习笔记7:前后端数据传输协议和异常处理
  • 阿里云事件总线 EventBridge 正式商业化,构建智能化时代的企业级云上事件枢纽
  • 【Spark征服之路-2.2-安装部署Spark(二)】
  • 力扣LeetBook数组和字符串--二维数组
  • 【无标题】路径着色问题的革命性重构:拓扑色动力学模型下的超越与升华
  • 网络测试实战:金融数据传输的生死时速
  • C++学习-入门到精通【14】标准库算法
  • C++11实现TCP网络通讯服务端处理逻辑简化版
  • ARM处理器工作模式
  • MCP通信方式之Streamable HTTP
  • ZooKeeper 安装教程(Windows + Linux 双平台)
  • Redis 安装配置和性能优化
  • 【bug】Error: /undefinedfilename in (/tmp/ocrmypdf.io.9xfn1e3b/origin.pdf)
  • 仓库拉下ssm项目配置启动
  • Java 高频面试题场景(四):社区老年大学在线学习平台系统
  • Android四大组件通讯指南:Kotlin版组件茶话会