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

[网络]tcp通信协议接口函数及一些简易项目

tcp是最常用的传输层协议,面向字节流,相较于其他协议,如udp;tcp更为复杂,tcp额外提供了可靠的、有序的和错误检测功能的数据传输服务.简单点来说,tcp更复杂,数据也更可靠

本文只是介绍tcp通信的一些接口,并不具体介绍tcp协议的内容以及各种策略

服务器端

1.socket

int socket(int domain, int type, int protocol);


// tcp协议对应的参数
int listensockfd = ::socket(AF_INET, SOCK_STREAM, 0);
  • 第一个参数domain 指定通信协议域,也就是下层的ip协议,常用有AF_INET(IPv4)、AF_INET6(IPv6)
  • 第二个参数type  指定套接字类型,SOCK_STREAM代表流式套接字,tcp是面向字节流的,所以使用这个
  • 第三个参数protocol    代表具体协议,0代表根据前两个选项自动推导,也可以设置为IPPROTO_TCP
  • 返回值      返回一个整数,代表文件描述符,在tcp里这个文件用来进行网络监听 ,此处和udp不同, 

2.bind

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);


// tcp协议参数
struct sockaddr_in local;
memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;            // 网络层协议
local.sin_port = htons(8888);          // 绑定自己的端口号
local.sin_addr.s_addr = INADDR_ANY;    // 绑定目标的ip,服务器使用INADDR_ANY代表谁都可以访问
int n = ::bind(_listensockfd, (struct sockaddr *)&local, sizeof(local));

  • 第一个参数是前面socket 的返回值
  • 第二个参数是一个c风格的多态,tcp使用sockaddr_in*.
  • 第三个参数是第二个参数指向内容的大小
  • 返回值    成功0,失败-1

3.listen

int listen(int sockfd, int backlog);


// tcp协议对应的参数
int n = ::listen(_listensockfd, 5);
  • 第一个参数是前面socket的返回值
  • 第二个参数是一个表示链接中间状态数量的整数,取决于当前服务器的性能,一般测试时给个5就可以
  • 返回值    成功0,失败-1

第二个参数的具体含义

        当调用listen后,tcp开始建立连接,但不能开始通信,直到调用accept函数,毫无疑问这一块一定是单线程的,效率较低;如果此时有大量客户端同时访问,服务器accept部分请求后,剩余的会因为长时间接收不到信息而退出。

        对于服务器来说,与其让大量客服端建立连接后傻等者,然后超时退出,不如直接一开始就不建立连接,相当于告诉他们别来了!

        listen的第二个参数代表服务器最多允许多少个客户端处于建立链接和开始通信的中间状态

4.accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);



// tcp协议对于的参数
struct sockaddr_in client;
socklen_t len = sizeof(client);
int sockfd = ::accept(_listensockfd, (struct sockaddr *)&client, &len);
  • 第一个参数是前面socket的返回值
  • 第二个参数是一个输出型参数,代表客户端的通信协议,ip和端口
  • 第三个参数是一个输入输出型参数(没见过吧,我也第一次见):本质是一个int*,输入时代表第二个参数的大小,输出时第二个参数被修改,代表新的第二个参数的大小
  • 返回值是一个文件描述符,用来进行网络通信

这个函数调用时会阻塞住线程,所以一般多线程的调用

客户端

1.socket(前面有,不多解释)

2.connect()

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);



// tcp协议对应的参数
struct sockaddr_in server;
memset(&server, 0, sizeof(server));

server.sin_family = AF_INET;
server.sin_port = htons(8888);
server.sin_addr.s_addr = ::inet_addr(127.0.0.1);
int n = ::connect(sockfd,(struct sockaddr *)&server, sizeof(server));
  • 参数和bind差不多,但底层关系不大
  • 第一个参数是前面socket 的返回值
  • 第二个参数是一个c风格的多态,tcp使用sockaddr_in*.
  • 第三个参数是第二个参数指向内容的大小
  • 返回值是一个文件描述符,用来进行网络通信

读写

得到文件描述符后可以进行读写,客户端和服务器共用一套读写函数

最简单的方法(因为tcp面向字节流,所以直接用文件的方式)

    while(true){
        std::string message;
        std::getline(std::cin,message);
        write(sockfd,message.c_str(),message.size());
        char buffer[1024];
        n = read(sockfd,buffer,sizeof(buffer));
        buffer[n] = 0;
        std::cout << buffer << std::endl;
    }
    ::close(sockfd);

专门的网络接口

ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);

个人制作的一些tcp小项目

linux/网络/2.tcp · 阿巴啊巴DDDD/计算机学 - 码云 - 开源中国

ok文章到这里结束了,如果能帮到你的话,可以给我点个赞赞吗


http://www.kler.cn/a/443544.html

相关文章:

  • Spring源码下载与测试
  • streamlit、shiny、gradio、fastapi四个web APP平台体验
  • 智能工厂的设计软件 应用场景的一个例子:为AI聊天工具添加一个知识系统 之11 方案再探 项目文件(修改稿1)
  • 四年匠心磨砺,快手系统软件技术创新与领域演进之路
  • chatwoot 开源客服系统搭建
  • 太速科技-519-基于ZU19EG的4路100G光纤的PCIe 加速计算卡
  • 【后端面试总结】深入解析进程和线程的区别
  • 《C++ 赋能强化学习:Q - learning 算法的实现之路》
  • 【Java 数据结构】如何写一副扑克牌 (附:全部码源) !!!
  • 量子通信学习路径(一)
  • JS使用random随机数实现简单的四则算数验证
  • transformer学习笔记-位置编码
  • 使用 NVIDIA DALI 计算视频的光流
  • 【设计模式】单例模式的应用场景
  • 计算机的错误计算(一百八十五)
  • AI-PR曲线
  • C++中如何实现单例模式?
  • 【Maven】基础(一)
  • 深度神经网络(DNN)在时序预测中的应用与缺陷
  • 前端 计算发布时间(如“1小时前”、“3天前”等)
  • Mybatis plus查询开用了Redis缓存,一开始挺快,用户多/时间拉长就变慢了
  • django基于python的图书馆管理系统
  • 重生之我在异世界学智力题(8)
  • Python中exifread库使用
  • microk8s使用
  • 通过枚举值调用函数