socket 基础
Socket是什么呢?
① Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。
② Socket是连接运行在网络上的两个程序间的双向通信的端点。
③ 网络通讯其实指的就是Socket间的通讯。
④ 通讯的两端都有Socket,数据在两个Socket之间通过IO来进行传输。
或者更通俗的解释: socket = ip + port
Socket原理?
基于tcp连接的socket 连接图


流式传输:“客户端”,
1.socket()函数;
2.bind()函数可有可无,加上指定传输端口,不加随机分配端口;
3.connect()函数,填写服务端的地址与端口【网络间通信AF_STREAM】或者路径【进程间通信AF_DGRAM】;
4.send()函数;
5.recv()函数。流式传输:“服务端”,
1.socket()函数;
2.bind()函数,必须加上指定传输端口【网络间通信AF_STREAM】或者是路径【进程间通信AF_DGRAM】;
3.listen()函数,使用isockfd;
5.accepc()函数,生成新的fd,inewfd;
6.send()函数,inewfd;
7.recv()函数,inewfd。
socket 接口函数
#include<sys/socket.h>//socket 函数
int socket(int domain, int type, int protocol)第一个参数domain指明了协议族,通常用AF_INET、AF_INET6、AF_LOCAL等。AF表示地址族,选择 AF_INET 的目的就是使用 IPv4 进行通信。因为 IPv4 使用 32 位地址,相比 IPv6 的 128 位来说,计算更快,便于用于局域网通信。第二个参数type是Socket类型,常用的Socket类型我们之前已经介绍过了分别是SOCK_STREAM和SOCK_DGRAM因为我们要写的是TCP Socket编程所以我们使用SOCK_STREAM。第三个参数protocol表示传输协议一般取为0。因为一般情况下有了 domain和 type 两个参数就可以创建套接字了,操作系统会自动推演出协议类型,除非遇到这样的情况:有两种不同的协议支持同一种地址类型和数据传输类型。如果我们不指明使用哪种协议,操作系统是没办法自动推演的。example:int sockfd = socket(AF_INET, SOCK_STREAM, 0); //建立套接字,基于TCPint sockfd = socket(AF_INET, SOCK_DGRAM, 0); //基于UDP
/=====================================================================///bind 函数
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 第一个参数sockfd为上一步创建socket时的返回值。第二个参数addr 为 sockaddr 结构体变量的指针。该类型的定义原型如下:struct sockaddr_in {short sin_family; //协议族,与前面Socket函数中提到的一样,我们这里使用AF_INETu_short sin_port; //端口号,需要struct in_addr sin_addr; //IP地址,需要使用网络序char sin_zero[8]; //没有实际意义,只是为了跟SOCKADDR结构在内存中对齐};第三个参数addrlen为addr 变量的大小,可由 sizeof() 计算得出。example:struct sockaddr_in serv_addr; //创建结构体变量servaddr.sin_family=AF_INET; //sin_family指代协议族和前面讲述socket()的第一个参数的含义相同,取值也需跟socke函数第一个参数值一样。servaddr.sin_port=htons(2000); //sin_port存储端口号(使用网络字节顺序,对于htons()函数我们还有单独一章的说明,2000这个端口转换为网络字节序列。//理论上端口号的取值范围为是0到65536,但0到1023的端口一般由系统分配给特定的服务程序,比如Web 服务的端口号为 80所以我们的程序要尽量在 1024~65536 之间分配端口号。servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"); //将iP地址127.0.0.1也就是本机地址转换为十进制bind(sockfd,(sockaddr*)&servaddr,sizeof(servaddr)); // 将套接字绑定到本地地址和端口上。
/=====================================================================///listen函数
int listen(int sockfd, int n);第一个参数为第一步sockfd创建socket时的返回值,套接字的描述符。第二个参数n用于指定接收队列的长度,也就是在Server程序调用accept函数之前最大允许进入的连接请求数,多余的连接请求将被拒绝,典型取值为5。example:listen(sockfd,5);//监听sockfd为创建套接字时的返回值。
/=====================================================================///accept函数
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);sockfd为建立socket函数返回的值。addr为 sockaddr 结构体变量的指针,这个参数是指针类型,是向外传内容的,即addr将在函数调用后填入对方(客户端)的地址信息,如对方的IP、端口等。addrlen为 addr变量的大小,可由 sizeof() 计算得出。 example:struct sockaddr_in clientaddr//创建客户端地址结构体int aID;//用来接收accept函数返回值aID = accept(sockfd,(sockaddr*)&clientaddr, sizeof( clientaddr));//等待接收客户连接请求
/=====================================================================///connect函数
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);sockfd:socket文件描述符addr:传出参数,返回链接客户端地址信息,含IP地址和端口号addrlen:传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小example:struct sockaddr_in server_addr;int cfd = socket(AF_INET, SOCK_STREAM, 0);bzero(&server_addr, sizeof(server_addr));server_addr.sin_family = AF_INET;inet_pton(AF_INET, CLIENT_IP, &server_addr.sin_addr.s_addr);server_addr.sin_port = htons(6666);connect(cfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
/=====================================================================///recv函数(tcp) & recvfrom( 通常用于UDP)
int recv (int fd, void *buf, int n, int flags);第一个参数fd,表示连接成功的套接字描述符。注意:这一步对于服务端而言是上一步accept的返回值;对于客户端而言是connect的返回值,并非是第一步socket创建套接字的返回值,不要搞混!第二个参数buf,就是为要接收的数据所在的缓冲区地址,也就是一个空的字符数组的首地址,这里放结果。第三个参数len为要接收数据的字节数。第四个参数flags为发送数据时的附带标记 ,一般情况下设置为0。但可以选择下列设置:MSG_DONTROUTE:表示不使用指定路由,对send、sendto有效MSG_PEEK:对recv, recvfrom有效,表示读出网络数据后不清除已读的数据MSG_OOB:对发送接收都有效,表示发送或接受加急数据example:char recBuf[200];//定义一个字符串用来保存客户端发来的数据recv(fd,recBuf,200,0);//接收来自客户端或服务端的数据recv缺省是阻塞函数,直到收到信息或出错才会返回
/=====================================================================///send函数(tcp) & sendto(通常用于UDP)
int send (int fd, const void *buf, int n, int flags);第一个参数fd,表示连接成功的套接字描述符。注意:这一步对于服务端而言是上一步accept的返回值;对于客户端而言是connect的返回值,并非是第一步socket创建套接字的返回值,不要搞混!第二个参数buf为要发送的数据所在的缓冲区地址,即一个已经存好内容的字符数组第三个参数len为要发送的数据的实际字节数+1。第四个参数flags为发送数据时的附带标记 ,一般情况下设置为0。但可以选择下列设置:MSG_DONTROUTE:表示不使用指定路由,对send、sendto有效 MSG_PEEK:对recv, recvfrom有效,表示读出网络数据后不清除已读的数据 MSG_OOB:对发送接收都有效,表示发送或接受加急数据example:char sendBuf[200];//定义一个数组用来保存发送的数据send(fd,sendBuf,strlen(sendBuf)+1,0);//用来发送服务端或客户端的数据与recv同样,send函数缺省也是阻塞函数,直到发送完毕或出错才会返回。需要注意,如果函数返回值与参数len不相等,则剩余未发送的信息需要再次发送/=====================================================================///close函数 && shutdown函数
int close (int fd);
int shutdown (int fd, int how) /* how determines what to shut down:SHUT_RD = No more receptions;SHUT_WR = No more transmissions;SHUT_RDWR = No more receptions or transmissions.*//=====================================================================/
socket 类似tcp 的工作原理


基于TCP(面向连接)的socket编程——流式套接字(SOCK_STREAM)
server.c
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>#define PORT 23 //端口号
#define BACKLOG 5 //最大监听数int main()
{int iSocketFD = 0; //socket句柄int iRecvLen = 0; //接收成功后的返回值int new_fd = 0; //建立连接后的句柄char buf[4096] = {0}; //struct sockaddr_in stLocalAddr = {0}; //本地地址信息结构图,下面有具体的属性赋值struct sockaddr_in stRemoteAddr = {0}; //对方地址信息socklen_t socklen = 0;//建立socketiSocketFD = socket(AF_INET, SOCK_STREAM, 0); if(0 > iSocketFD){printf("创建socket失败!\n");return 0;} stLocalAddr.sin_family = AF_INET; /*该属性表示接收本机或其他机器传输*/stLocalAddr.sin_port = htons(PORT); /*端口号*/stLocalAddr.sin_addr.s_addr=htonl(INADDR_ANY); /*IP,括号内容表示本机IP*///绑定地址结构体和socketif(0 > bind(iSocketFD, (void *)&stLocalAddr, sizeof(stLocalAddr))){printf("绑定失败!\n");return 0;}//开启监听 ,第二个参数是最大监听数if(0 > listen(iSocketFD, BACKLOG)){printf("监听失败!\n");return 0;}printf("iSocketFD: %d\n", iSocketFD); //在这里阻塞知道接收到消息,参数分别是socket句柄,接收到的地址信息以及大小 new_fd = accept(iSocketFD, (void *)&stRemoteAddr, &socklen);if(0 > new_fd){printf("接收失败!\n");return 0;}else{printf("接收成功!\n");//发送内容,参数分别是连接句柄,内容,大小,其他信息(设为0即可) send(new_fd, "这是服务器接收成功后发回的信息!", sizeof("这是服务器接收成功后发回的信息!"), 0);}printf("new_fd: %d\n", new_fd); iRecvLen = recv(new_fd, buf, sizeof(buf), 0); if(0 >= iRecvLen) //对端关闭连接 返回0{ printf("接收失败或者对端关闭连接!\n");}else{printf("buf: %s\n", buf);}close(new_fd);close(iSocketFD);return 0;
}
client.c
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>#define PORT 23 //目标地址端口号
#define ADDR "192.168.1.230" //目标地址IPint main()
{int iSocketFD = 0; //socket句柄unsigned int iRemoteAddr = 0;struct sockaddr_in stRemoteAddr = {0}; //对端,即目标地址信息socklen_t socklen = 0; char buf[4096] = {0}; //存储接收到的数据//建立socketiSocketFD = socket(AF_INET, SOCK_STREAM, 0); if(0 > iSocketFD){printf("创建socket失败!\n");return 0;} //绑定服务器的ip地址和端口stRemoteAddr.sin_family = AF_INET;stRemoteAddr.sin_port = htons(PORT);inet_pton(AF_INET, ADDR, &iRemoteAddr);stRemoteAddr.sin_addr.s_addr=iRemoteAddr;//connet()连接方法: 传入句柄,目标地址,和大小if(0 > connect(iSocketFD, (void *)&stRemoteAddr, sizeof(stRemoteAddr))){printf("连接失败!\n");//printf("connect failed:%d",errno);//失败时也可打印errno}else{printf("连接成功!\n");recv(iSocketFD, buf, sizeof(buf), 0);//将接收数据打入buf,参数分别是句柄,储存处,最大长度,其他信息(设为0即可)。 printf("Received:%s\n", buf);}close(iSocketFD);//关闭socket return 0;
}
相关文章:
socket 基础
Socket是什么呢? ① Socket通常也称作“套接字”,用于描述IP地址和端口,是一个通信链的句柄。应用程序通常通过“套接字”向网络发出请求或者应答网络请求。 ② Socket是连接运行在网络上的两个程序间的双向通信的端点。 ③ 网络通讯其实指…...
JMeter(二十五)、一些概念的理解---90%响应时间、事务、并发
Jmeter中一些概念的理解——90%响应时间、事务、并发 一、90%响应时间(参考虫师博客) 90%Line 一组数由小到大进行排列,找到他的第90%个数(假如是12),那么这个数组中有90%的数将小于等于12 。 用在性能测试的响应时间,也就是90%请求响应时间不会超过12 秒。 例如:…...
直播课 | 大橡科技研发总监丁端尘博士“类器官芯片技术在新药研发中的应用”
从类器官到类器官芯片,正在生物科学领域大放异彩。 药物研发需要新方法 众所周知,一款新药是一个风险大、周期长、成本高的艰难历程,国际上有一个传统的“双十”说法——10年时间,10亿美金,才可能成功研发出一款新药…...
Python中的PDF文本提取:使用fitz和wxPython库(带进度条)
引言: 处理大量PDF文档的文本提取任务可能是一项繁琐的工作。本文将介绍一个使用Python编写的工具,可通过简单的操作一键提取大量PDF文档中的文本内容,极大地提高工作效率。 import wx import pathlib import fitzclass PDFExtractor(wx.Fr…...
mysql 将字段值+1或自增
一、解决方式: SET var 1; UPDATE jes_menu_info SET MENU_SORT (var : var 1) WHERE ss_idACC; 二、解读用户变量,在客户端链接到数据库实例整个过程中用户变量都是有效的。 MySQL中用户变量不用事前申明,在用的时候直接用“变量名”使…...
组合总和——力扣39
文章目录 题目描述回溯 题目描述 回溯 class Solution { public:vector<vector<int>> res;vector<int> seq; void dfs(vector<int>& nums, int pos, int target){if(target0){res.emplace_back(seq);return;}if(posnums.size()){return;}//直接跳过…...
PostgreSQL Patroni_exporter 监控 patroni高可用工具
Patroni是Cybertec公司基于python语言开发的,可用于使用流复制来创建,管理,维护和监视高可用性PostgreSQL集群设置的工具。 目前,PatroniEtcd 是最为推荐的PostgreSQL数据库高可用方案之一。 PostgreSQL有postgres_exporter监控采…...
C语言多级指针
#include "stdio.h" #include <stdlib.h>int main() {int a 10;//*p int a int *pint* p &a;int** q &p;//int** q int *(*q) int *(q) a//int**q int*(*q) int*(&a) int*&a aint*** k &q;//分析:首先k是个变量&…...
IDEA项目实践——创建Java项目以及创建Maven项目案例、使用数据库连接池创建项目简介
系列文章目录 IDEA上面书写wordcount的Scala文件具体操作 IDEA创建项目的操作步骤以及在虚拟机里面创建Scala的项目简单介绍 目录 系列文章目录 前言 一 准备工作 1.1 安装Maven 1.1.1 Maven安装配置步骤 1.1.2 解压相关的软件包 1.1.3 Maven 配置环境变量 1.1.4 配…...
ArraySetter
简介 用来展示属性类型为数组的 setter 展示 配置示例 "setter": {"componentName": "ArraySetter","props": {"itemSetter": {"componentName": "ObjectSetter","props": {"c…...
Python如何解决Amazon亚马逊“图文验证码”识别(6)
前言 本文是该专栏的第55篇,后面会持续分享python爬虫干货知识,记得关注。 在本专栏前面,笔者有详细介绍多种登录验证码识别方法,感兴趣的同学可往前翻阅。而本文,笔者将单独详细介绍亚马逊Amazon的图文识别验证码的解决方法。 如上图所示,访问或请求频次达到一定程度之…...
plsql连接oracle出现TTC错误
这个错误莫名其妙,搜不到直接关联的解决方案。用了下面解决乱码的方式倒是解决了。 ORA-03137: TTC protocol internal error : [%s] [%s] [%s] [%s] [%s] [%s] [%s] [%s] 按照如下链接解决: PL/SQL Developer中文乱码解决方案_Bug君坤坤的博客-CSDN博…...
4-golang爬虫下载的代码
golang爬虫下载的代码: 下载程序的借鉴内容: 这个是关于gbk,utf8等相互转换的包 github.com/axgle/mahonia" 一、标准下载代码 package downloaderimport ("log""net/http""io""github.com/axgle/…...
Eureka增加账号密码认证登录
一、业务背景 注册中心Eureka在微服务开发中经常使用到,用来管理发布的微服务,供前端或者外部调用。但是如果放到生产环境,我们直接通过URL访问的话,这显然是不安全的。 所以需要给注册中心加上登录认证。 通过账号和密码认证进行…...
Practice5|58. 最后一个单词的长度、66. 加一
58. 最后一个单词的长度 1.题目: 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 示例 1: 输入:…...
Practice4|14. 最长公共前缀、2. 两数相加
14. 最长公共前缀 1.题目: 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀,返回空字符串 ""。 示例 1: 输入:strs ["flower","flow","flight"] 输出…...
第28天-Kubernetes架构,集群部署,Ingress,项目部署,Dashboard
1.K8S集群部署 1.1.k8s快速入门 1.1.1.简介 Kubernetes简称k8s,是用于自动部署,扩展和管理容器化应用程序的开源系统。 中文官网:https://kubernetes.io/zh/中文社区:https://www.kubernetes.org.cn/官方文档:https…...
剑指OfferII-58.左旋转字符串
剑指OfferII-58.左旋转字符串 目录 剑指OfferII-58.左旋转字符串题目描述解法一:字符数组解法二:原地反转 题目描述 字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。 请定义一个函数实现字符串左旋转操作的功能。 比如,…...
C语言每日一题:14《数据结构》复制带随机指针的链表
题目一: 题目链接: 思路一: 找相对位置暴力求解的方法: 1.复制一个新的链表出来遍历老的节点给新的节点赋值,random这个时候不去值。 2.两个链表同时遍历,遍历老链表的时候去寻找相对位置,在遍…...
MySql008——检索数据:过滤数据(WHERE子句的使用)
前提:使用《MySql006——检索数据:基础select语句》中创建的products表 一、实际需求 数据库表一般包含大量的数据,但是很少需要检索表中所有行。通常只会根据特定条件提取表数据的子集。只检索所需数据需要指定搜索条件(search …...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
