Socket通信基础

1 基本概念

socket是操作系统提供的一套标准化网络编程接口,应用程序调用这些接口,可以编写出服务端(Server)和客户端(Client)的socket程序,两端的socket通过特定的IP地址端口连接起来,获得通信能力。

1.1 基本原理

我们可以将socket视作一个功能库,它提供了一套标准的API。
socket库自带了解析器,会对接到对应的操作系统接口。而操作系统的相关部分,就是TCP/IP协议等一些列的网络协议栈。经过协议栈的解析后,就会送到对应的网卡驱动,再之后就是硬件传输了。
在这里插入图片描述
站在TCP/IP五层网络模型的层面,socket,就是传输层向应用层提供的一个使用接口。

2 使用socket

2.1 接口流程

socket底层原理比较复杂,涉及到操作系统和网络通信的各种协议编解码,但使用起来并不是很麻烦。
在这里插入图片描述

2.2 接口定义

下面先详细介绍一下各个接口的使用方法。

2.2.1 socket

socket是创建套接字,返回值是套接字的文件描述符fd

int socket(int af, int type, int protocol);
  • af:地址族(Address Family),常用的有 AF_INET 和 AF_INET6,分别对应 IPv4 和 IPv6。
  • type:传输方式,常用的有 SOCK_STREAM(面向连接的流格式) 和 SOCK_DGRAM(无连接的数据报套接字)。
  • protocol:传输协议,常用的有 IPPROTO_TCP 和 IPPTOTO_UDP,分别对应 TCP 和 UDP。
// sockaddr直接使用数组保存数据,可读性差
struct sockaddr{sa_family_t  sin_family;   //地址族char         sa_data[14];  //IP地址和端口号
};
// sockaddr_in有具体成员变量名,可读性好。两者大小等同
struct sockaddr_in{sa_family_t     sin_family;   //地址族uint16_t        sin_port;     //16位的端口号struct in_addr  sin_addr;     //32位IP地址char            sin_zero[8];  //不使用
};

2.2.2 bind

bind()是将套接字与特定的 IP 地址和端口绑定。

int bind(int sock, struct sockaddr *addr, socklen_t addrlen);
  • sock:套接字文件描述符(由 socket() 创建)
  • addr:套接字地址信息,通常使用 struct sockaddr_in来转换
  • addrlen:addr的长度,直接使用sizeof计算

2.2.3 accept

accept() 用于服务端来接受客户端请求,参数和 bind() 相同

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

返回值为当前连接的文件描述符。

2.2.4 connect

connect() 用于客户端去和服务端建立连接,参数和 bind() 相同。

int connect(int sock, struct sockaddr *serv_addr, socklen_t addrlen);

注意这里sockaddr为服务端的地址信息.

2.2.5 listen

listen() 用于服务端进入监听状态。

int listen(int sock, int backlog);
  • sock:套接字文件描述符。
  • backlog:请求队列的长度。填 SOMAXCONN 表示由系统来决定

2.2.6 recv

recv()用于从客户端文件描述符接收数据。

int recv(int sockid, void* buf, size_t len, int flags);
  • sockid:对于服务端accept函数时,应该使用和当前客户端的文件描述符,不是监听的文件描述符
  • flags:
  • MSG_WAITALL:如果设置了此参数,recv将阻塞到至少有len个字节的数据可用
  • MSG_DONTWAIT: 如果设置了此参数,recv将采用非阻塞的模式,即使没有数据也会立即返回
  • MSG_PEEK:如果设置了此标记,recv将从套接字客户端文件描述符的接收队列读取数据,但不会将其从队列中移除。

2.2.7 其他

剩余的 write()、read()、close() 就是标准的 Linux 调用,句柄就是 socket() 创建的文件描述符,此处不再赘述。

3 代码应用

3.1 服务端代码

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>using namespace std;int main(int argc ,char *argv[])
{if(argc !=2 ){cout<<"use \"./server port\" to start"<<endl;}// 1.创建服务端socketint listenfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(listenfd == -1){perror("socket");return -1;}// 2. 将服务端描述符 bind到通信的ip和端口sockaddr_in srvAddr = {0};srvAddr.sin_family = AF_INET;//srvAddr.sin_addr.s_addr = htonl(IPADDR_ANY);inet_pton(AF_INET, "127.0.0.1", &srvAddr.sin_addr);srvAddr.sin_port = htons(atoi(argv[1]));if(bind(listenfd, (sockaddr*)&srvAddr, sizeof(srvAddr)) != 0){perror("bind error!");close(listenfd);return -1;}// 3.把socket设置为可连接状态if(listen(listenfd, 5) != 0){perror("listen error!");close(listenfd);return -1;}//4. 受理客户端的连接请求,如果没有客户端连上来,accept将一直阻塞sockaddr_in clientAddr;socklen_t len = sizeof(sockaddr_in);int clientfd = accept(listenfd, &clientAddr, &len));if(clientfd == -1){std::cerr<<"error accept connection"<<std::endl;close(listenfd);return -1;}// 5. 与客户端通信char buff[1024];while(true){int iret;memset(buff, 0 ,sizoef(buff));//阻塞函数,如果客户端已断开,则函数返回0iret = recv(clientfd, buffer, sizeof(buff), 0);if(iret <= 0){cout<<"iret:"<<iret<<endl;break}cout<<"recv content:"<<buff<<endl;strcpy(buffer, "ok");if( (iret=send(clientfd, buff, sizeof(buff), 0)) <= 0 ){std::cout<<"send error"<<endl;break;}cout<<"send:"<<buff<<endl;}//6.关闭套接字close(listenfd);close(clientfd);
}

3.2 客户端代码

#include <iostream>
#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <apra/inet.h>
#include <netdb.h>using namespace std;int main(int argc ,char *argv[])
{if(argc !=3 ){cout<<"use \"./client serverip port\" to start"<<endl;}// 1.创建客户端socketint sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(sockfd == -1){perror("socket");return -1;}// 2. 发起connect连接struct hostent* h;if((h=gethostbyname(argv[1])) == 0){cout<<"get server addr error"<<endl;return -1;}sockaddr_in srvAddr = {0};srvAddr.sin_family = AF_INET;memcpy(srvAddr.sin_addr, h->h_addr, h->h_length);srvAddr.sin_port = htons(atoi(argv[2]));if(connect(sockfd, (sockaddr*)&srvAddr, sizeof(srvAddr)) ! = 0){perror("connect error!");close(sockfd);return -1;}// 3.与服务端通信char buff[1024];for(int i=0; i< 10; ++i){int iret;memset(buff, 0 ,sizeof(buff));sprintf(buff, "this is the %d girl.", i);iret = send(sockfd, buff, sizeof(buff), 0);if(iret <= 0){cout<<"iret:"<<iret<<endl;break;}cout<<"send:"<<buff<<endl;memset(buff, 0 ,sizeof(buff));if( (iret=recv(sockfd, buff, sizeof(buff), 0)) <= 0 ){std::cout<<"send error"<<endl;break;}cout<<"recv:"<<buff<<endl;sleep(1);}//4.关闭套接字close(sockfd);
}

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

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

相关文章

短视频账号矩阵系统源码---独立saas技术部署

#短视频账号矩阵系统# #短视频矩阵源码# #短视频账号矩阵系统技术开发# 抖音seo账号矩阵系统&#xff0c;短视频矩阵系统源码&#xff0c; 短视频矩阵是一种常见的视频编码标准&#xff0c;通过多账号一键授权管理的方式&#xff0c;为运营人员打造功能强大及全面的“矩阵式“…

html 轮播图效果

轮播效果&#xff1a; 1、鼠标没有移入到banner,自动轮播 2、鼠标移入&#xff1a;取消自动轮播、移除开始自动轮播 3、点击指示点开始轮播到对应位置 4、点击前一个后一个按钮&#xff0c;轮播到上一个下一个图片 注意 最后一个图片无缝滚动&#xff0c;就是先克隆第一个图片…

Linux -- 进程间通信、初识匿名管道

目录 进程间通信 什么是进程间通信 进程间通信的一般规律 前言&#xff1a; 管道 代码预准备&#xff1a; 如何创建管道 -- pipe 函数 参数&#xff1a; 返回值&#xff1a; wait 函数 参数&#xff1a; 验证管道的运行&#xff1a; 源文件 test.c &#xff1a; m…

能源管理系统

一、介绍 基于SpringCloud的能管管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码 二、软件架构 二、功能介绍 三、数字大屏展示 四、数据采集原理 五、软件截图

小渡Al论文写作:50个GPT学术指令——1天搞定1篇论文

选题与研究方向 假设你是某高校某专业的教授&#xff0c;请根据我感兴趣的研究方向&#xff0c;为我提供10个新颖且有研究意义的论文选题。我对某个选题感兴趣&#xff0c;请列举几个该领域当前的研究热点和争议点供我选择。假设我是某专业本科生/研究生&#xff0c;请为我提供…

Unreal Engine5安装Niagara UI Renderer插件

系列文章目录 文章目录 系列文章目录前言一、如何下载安装Niagara UI Renderer插件 前言 在2024.10.24号的今天发现unreal engine官网已经没有虚幻商城了&#xff0c;取而代之的是FAB ‌虚幻商城已经停止运营&#xff0c;Epic Games推出了新的数字资产商店FAB。‌ Epic Games…

Python URL编码

在 Python 中&#xff0c;可以使用 urllib.parse模块对 URL 进行编码。 一、依赖安装 pip install urllib 二、URL编码 from urllib.parse import quoteurl rhttps://myshop.com/shop/shopList?query query {"id":14,"pageSize":10,"pageNum&quo…

【论文+源码】基于SSM+VUE的大学生兼职管理系统

创建一个大学生兼职管理系统&#xff0c;结合 SSM&#xff08;Spring Spring MVC MyBatis&#xff09;框架和 Vue.js 前端框架&#xff0c;可以分为几个主要步骤来实现。 第一部分&#xff1a;环境准备 1. 开发环境准备 Java JDK&#xff1a;确保已安装 Java 8 或更高版本。…

2024软考网络工程师笔记 - 第8章.网络安全

文章目录 网络安全基础1️⃣网络安全威胁类型2️⃣网络攻击类型3️⃣安全目标与技术 &#x1f551;现代加密技术1️⃣私钥密码/对称密码体制2️⃣对称加密算法总结3️⃣公钥密码/非对称密码4️⃣混合密码5️⃣国产加密算法 - SM 系列6️⃣认证7️⃣基于公钥的认证 &#x1f552…

从0开始深度学习(19)——参数管理

在选择了模型架构&#xff0c;并设置了超参数之后&#xff0c;就进入了训练阶段&#xff0c;此时&#xff0c;我们的目标是找到使损失函数最小化的模型参数值。 经过训练后&#xff0c;我们将需要使用这些参数来做出未来的预测。 此外&#xff0c;有时我们希望提取参数&#xf…

背包九讲——完全背包问题

目录 完全背包问题 问题定义 动态规划解法 状态转移方程 初始化 遍历顺序 三种解法&#xff1a; 朴素版——枚举k 进阶版——dp正推&#xff08;一维滚动数组&#xff09; 背包问题第三讲——完全背包问题 背包问题是一类经典的组合优化问题&#xff0c;通常涉及在限定…

【Linux笔记】Linux命令与使用

博文将不断学习补充 学习参考博文&#xff1a; Linux命令大全&#xff1a;掌握常用命令&#xff0c;轻松使用Linux操作系统-CSDN博客 文件或目录操作命令 zip # zip是使用最多的文档压缩格式 # 方便跨平台使用&#xff0c;但是压缩率不是很高 zip指令未安装 安装zip yum ins…

python实战项目47:Selenium采集百度股市通数据

python实战项目47:Selenium采集百度股市通数据 一、思路分析二、完整代码一、思路分析 这里以获取百度股市通股评下的投票数据为例,页面中的其他数据同理。由于此页面数据是js动态加载的,所以采用Selenium获取数据。思路很简单,通过Selenium打开页面,然后定位到“股评”选…

没有B柱?极氪MIX太大胆了!

文 | AUTO芯球 作者 | 雷慢 极氪又给国产车长脸了&#xff0c; 极氪MIX上市&#xff0c;创造了多个行业先例&#xff0c; 估计把合资看得一愣一愣的&#xff0c; 哪见过这样的每月都有新技术、黑科技冒出来&#xff0c; 我看完整个发布会就一个感想&#xff0c; 家里有小…

数据结构——哈夫曼树及其应用(哈夫曼编码)

判断树&#xff1a;用来描述分类过程的二叉树 哈夫曼树&#xff08;最优二叉树&#xff09;的基本概念 路径&#xff1a;从树中一个结点到另一个结点之间的分支构成这两个结点间的路径。 结点的路径长度&#xff1a;两结点间路径上的分支数。 结点的路径长度计算&#xff1…

PDF文件为什么不能编辑是?是啥原因导致的,有何解决方法

PDF文件格式广泛应用于工作中&#xff0c;但有时候我们可能遇到无法编辑PDF文件的情况。这可能导致工作效率降低&#xff0c;特别是在需要修改文件内容时显得尤为棘手。遇到PDF不能编辑时&#xff0c;可以看看是否以下3个原因导致的。 一、文件受保护 有些PDF文件可能被设置了…

leetcode动态规划(十二)-最后一块石头的重量

题目 1049.最后一块石头的重量 有一堆石头&#xff0c;用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合&#xff0c;从中选出任意两块石头&#xff0c;然后将它们一起粉碎。假设石头的重量分别为 x 和 y&#xff0c;且 x < y。那么粉碎的可能结…

矩阵matrix

点积 在 NumPy 中&#xff0c;dot 是矩阵或向量的点积&#xff08;dot product&#xff09;操作。 假设有两个向量a和 b&#xff0c;它们的点积定义为对应元素相乘&#xff0c;然后求和。公式如下&#xff1a; 例子&#xff1a; 点积的计算步骤是&#xff1a; 因此&#xf…

入门 | Prometheus+Grafana 普罗米修斯

一、prometheus介绍 1、监控系统组成 一个完整的监控系统需要包括如下功能&#xff1a;数据产生、数据采集、数据存储、数据处理、数据展示、分析、告警等。 &#xff08;1&#xff09;、数据来源 数据来源&#xff0c;也就是需要监控的数据。数据常见的产生、直接或间接暴露…

服务器磁盘爆满?别慌,教你轻松清理!

服务器磁盘爆满&#xff1f;别慌&#xff0c;教你轻松清理&#xff01; 简介 服务器磁盘空间告急&#xff0c;网站访问缓慢&#xff0c;甚至无法正常运行&#xff1f;别担心&#xff0c;这篇文章将为你提供一份详细的清理指南&#xff0c;帮助你快速释放服务器磁盘空间&#x…