TCP编程
1.socket函数
int socket(int domain, int type, int protocol);
头文件:include<sys/types.h>,include<sys/socket.h>
参数
int domain
AF_INET: IPv4 Internet protocols
AF_INET6: IPv6 Internet protocols
AF_UNIX, AF_LOCAL : Local communication
- AF NETLINK:kernel user interface device
- AF_PACKET: low level packer interface
type
- SOCK_STREAM:流式接字 唯一对应TCP
- SOCK_DGRAM:数据包套接字,唯一对应UDP
- SOCK_RAM :原始套接字
protocol:
一般填0,原始套接字编程时需填充
返回值: 成功返回文件描述符,出错返回-1
socket函数对应于普通文件的打开操作。普通文件的打开操作返回一个文件描述字,而socket()用于创建 一个socket描述符 (socket descriptor),它唯一标识一个socket。这个socket描述字跟文件描述字一样,后续的操作都 有用到它,把它作为参 数,通过它来进行一些读写操作。创建socket的时候,也可以指定不同的参数创建不同的socket描述 符,socket函数的三个参数 分别为: domain:即协议域,又称为协议族(family)。常用的协议族有,AF_INET、AF_INET6、 AF_LOCAL(或称AF_UNIX, Unix域socket)、AF_ROUTE等等。协议族决定了socket的地址类型,在通信中必须采用对应的地址, 如AF_INET决定了 要用ipv4地址(32位的)与端口号(16位的)的组合、AF_UNIX决定了要用一个绝对路径名作为地址。 type:指定socket类型。常用的socket类型有,SOCK_STREAM、SOCK_DGRAM、SOCK_RAW、 SOCK_PACKET、 SOCK_SEQPACKET等等(socket的类型有哪些?)。 protocol:故名思意,就是指定协议。常用的协议有,IPPROTO_TCP、IPPTOTO_UDP、 IPPROTO_SCTP、 IPPROTO_TIPC等,它们分别对应TCP传输协议、UDP传输协议、STCP传输协议、TIPC传输协议,type 和protocol并不 是可以随意组合的,如SOCK_STREAM不可以跟IPPROTO_UDP组合。当protocol为0时,会自动选择 type类型对应的默 认协议。
2.bind绑定函数
int bind(
int sockfd,
struct sockaddr *my_addr,
int addrlen);
参数:
sockfd:通过socket()函数拿到的fd
addr:采用 struct socket的结构体地址
struct sockaddr ( //通用结构体
unsigned short sa_family; // 2个字
char sa_data[14]; // 14字节的协议地址
);
struct socket_in{ //基于socket通信结构体
sa family t sin family://两个字节
in_port_t sin_port; //两个字节
struct in_addr sin_addr;// 四个字节\
sin zero[8];//八位,填充字节,需清零
}
struct in_addr(
uint32_ts_addr; //32位网络字节序}
addrlen:地址长度
返回值:
成功返回0出错返回-1
当我们调用socket创建一个socket时,返回的socket描述字它存在于协议族(address family, AF_XXX)空间中,但没有一个 具体的地址。如果想要给它赋值一个地址,就必须调用bind()函数。通常服务器在启动的时候都会绑定 一个众所周知的地址(如 ip地址+端口号),用于提供服务,客户就可以通过它来接连服务器;而客户端就不用指定,由系统自动 分配一个端口号和自身 的ip地址组合。这就是为什么通常服务器端在listen之前会调用bind(),而客户端就不会调用,而是在 connect()时由系统随机生 成一个。当然客户端也可以在调用connect()之前bind一个地址和端口,这样就能使用特定的IP和端口来 连服务器了。
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
函数的三个参数分别为:
sockfd:即socket描述字,它是通过socket()函数创建了,唯一标识一个socket。bind()函数就是将给这 个描述字绑定一 个名字。
addrlen:对应的是地址的长度。
addr:一个const struct sockaddr *指针,指向要绑定给sockfd的协议地址。
这个地址结构根据地址创 建socket时的地 址协议族的不同而不同,但最终都会强制转换后赋值给sockaddr这种类型的指针传给内核:
通用套接字 sockaddr 类型定义:
ipv4对应的是sockaddr_in类型定义:
ipv6对应的sockaddr_in6类型定义:
网络字节序和主机字节序
主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数 在内存中保存的顺序,
主机字节序就是我们平常说的大端和小端模式:不同的CPU有不同的字节序类型,这些字节序是指整数 在内存中保存的顺序, 这个叫做主机序。引用标准的Big-Endian和Little-Endian的定义如下: a) Little-Endian就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 b) Big-Endian就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
网络字节序:4个字节的32 bit值以下面的次序传输:首先是0~7bit,其次8~15bit,然后16~23bit, 最后是24~31bit。这 种传输次序称作大端字节序。由于TCP/IP首部中所有的二进制整数在网络中传输时都要求以这种次序, 因此它又称作网络字节 序。字节序,顾名思义字节的顺序,就是大于一个字节类型的数据在内存中的存放顺序,一个字节的数 据没有顺序的问题了。 所以: 在将一个地址绑定到socket的时候,请先将主机字节序转换成为网络字节序,再赋给socket。
serv_addr.sin_port = htons(LISTEN_PORT);
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
这里通过调用两个函数 htons() 和 htolnl() 分别用来将 端口和IP地址转换成网络字节序,这两个函数名 中的 h表示host, n表 示network, s表示short(2字节/16位), l表示long(4字节/32位)。因为端口号是16位的,所以我们用 htons()把端口号从主机字节 序转换成网络字节序, 而IP地址是32位的,所以我们用htonl()函数把IP地址从主机字节序转换成网络字 节序。INADDR_ANY 就是指定地址为0.0.0.0的地址,这个地址事实上表示不确定地址,或“所有地址”、“任意地址”。 一般来说,在各个系统中均 定义成为0值。这里也就意味着监听所有的IP地址。
3.listen()函数
int listen(int sockfd, int backlog);
参数:
sockfd:通过socket()函数拿到的fd;
backLog:同时允许几路客户端和服务器进行正在连接的过程(正在三次握手),一般填5。
内核中服务器的套接字fd会维护2个链表
1.正在三次握手的客户端链表(数量=2*backlog+1)
2.已经建立好连接的客户端链表(已经完成三次握手分配好了的newfd)
返回值:
成功返回0
出错返回-1
listen(fd, 5);//表示系统允许11 (2*5+1)个客户端同时进行三次握手
4.accept()函数
阻塞等待客户端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数
sockfd:经过前面socket()创建并通过bind(),listen()设置过的fd
addr:指向存放地址信息的结构体的首地址(获取客户端IP地址和端口号)
addrlen:存放地址信息的结构体的大小
返回值
成功,返回返回已经建立连接的新的newfd
出错, 返回-1
服务器代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include<sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT”
#define BUFSIZE 1024
#define BACKLOG 5
#define SERV_IP 5001
#define SERV IP ADDR "192.168.182.144"
int main()
{int fd = -1;struct sockaddr_in sin;//1.socketfd = socket(AF_INET, SOCK_STREAM, 0);if(fd <0){perror(“socket");exit(1);}bzero(&sin, sizeof(sin));sin.sin family = AF_INET;sin.sin port = htons(SERV IP);sin.sin addr.s addr = inet addr(SERV IP ADDR);/*if(inet_pton(AF_INET, SERV_IP_ADDR,(votd *)&stn.sin_addr.s_addr) != 1)perror("inet_pton");exit(1);*///2.bindif(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) <0){perror("bind");exit(1)}//3.listenif(listen(fd, BACKLOG) <0){perror("Listen");exit(1);}//4.acceptint newfd = -1;newfd = accept(fd, NULL, NULL);if(newfd <0){perror("accept");exit(1);}char buf[BUFSIZE];int ret = -1;//readwhile(1){do{bzero(buf, BUFSIZE);ret = read(newfd, buf, BUFSIZE-1);}while(ret <1);if(ret <0){exit(1);}if(!ret){break;}printf("receive data:%s\n", buf);if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){printf("Client is exiting!\n");break;}}
close(newfd);
close(fd);
return 0;
5.客户端连接函数connect()
int connect (int[sockfd, struct sockaddr * serv_addr, int addrlen)
参数:
sockfd:通过socket()函数拿到的fd
addr:struct sockaddr的结构体变量地址
addrlen:地址长度
返回值:
成功,返回0
失败,返回-1
客户端代码
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT"
#define BUFSIZE 1024
#define SERV_PORT 5001
#define SERV_IP_ADDR "192.168.182.144”
int main()
{int fd = -1;struct sockaddr_in sin;fd = socket(AF_INET, SOCK_STREAM, Gif(fd <0){perror("socket");exit(1);}bzero(&sin,sizeof(sin));sin.sin family = AF_INET;sin.sin port = htons(SERV_PORT);sin.sin_addr.s _addr= inet_addr(SERV_IP_ADDR);if(connect(fd, (struct sockaddr*)&sin, sizeof(sin))<0){perror("connect");exit(1);}char buf[BUFSIZE];while(1){bzero(buf, BUFSIZE);if(fgets(buf, BUFSIZE-1, stdin) == NULL){continue;}write(fd, buf, strlen(buf));if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){break;}return 0;
}
TCP服务获取客户端IP地址
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include<sys/socket.h>
#include <strings.h>
#include <arpa/inet.h>
#define QUIT_STR "QUIT”
#define BUFSIZE 1024
#define BACKLOG 5
#define SERV_IP 5001
#define SERV IP ADDR "192.168.182.144"
int main()
{int fd = -1;struct sockaddr_in sin;//1.socketfd = socket(AF_INET, SOCK_STREAM, 0);if(fd <0){perror(“socket");exit(1);}bzero(&sin, sizeof(sin));// sin.sin family = AF_INET;sin.sin port = htons(SERV IP);//sin.sin addr.s addr = inet addr(SERV IP ADDR);sin.sin addr.s addr =ADDR_ANY;/*if(inet_pton(AF_INET, SERV_IP_ADDR,(votd *)&stn.sin_addr.s_addr) != 1)perror("inet_pton");exit(1);*///2.bindif(bind(fd, (struct sockaddr *)&sin, sizeof(sin)) <0){perror("bind");exit(1);}//3.listenif(listen(fd, BACKLOG) <0){perror("Listen");exit(1);}//4.accept/*int newfd = -1;newfd = accept(fd, NULL, NULL);if(newfd <0){perror("accept");exit(1);}*/int newfd = -1;struct sockaddr _in cin;socklen_t addrlen = sizeof(cin);newfd = accept(fd, (struct sockaddr *)&cin, &addrlen);if(newfd <0){perror("accept");exit(1);}char ipv4_addr[16];if(!inet_ntop(AF_INET, (void *)&cin.sin _addr, ipv4_addr, sizeof(cin))){perror("inet_ntop");exit(1);}printf("Clint:(%s, %d)is connect!\n", ipv4 addr, ntohs(cin.sin_port));char buf[BUFSIZE];int ret = -1;//readwhile(1){do{bzero(buf, BUFSIZE);ret = read(newfd, buf, BUFSIZE-1);}while(ret <1);if(ret <0){exit(1);}if(!ret){break;}printf("receive data:%s\n", buf);if(!strncasecmp(buf, QUIT_STR, strlen(QUIT_STR))){printf("Client is exiting!\n");break;}}
close(newfd);
close(fd);
return 0;
相关文章:

TCP编程
1.socket函数 int socket(int domain, int type, int protocol); 头文件:include<sys/types.h>,include<sys/socket.h> 参数 int domain AF_INET: IPv4 Internet protocols AF_INET6: IPv6 Internet protocols AF_UNIX, AF_LOCAL : Local…...
OpenAI 实战进阶教程 - 第七节: 与数据库集成 - 生成 SQL 查询与优化
内容目标 学习如何使用 OpenAI 辅助生成和优化多表 SQL 查询了解如何获取数据库结构信息并与 OpenAI 结合使用 实操步骤 1. 创建 SQLite 数据库示例 创建数据库及表结构: import sqlite3# 连接 SQLite 数据库(如果不存在则创建) conn sq…...
Apache Iceberg数据湖技术在海量实时数据处理、实时特征工程和模型训练的应用技术方案和具体实施步骤及代码
Apache Iceberg在处理海量实时数据、支持实时特征工程和模型训练方面的强大能力。Iceberg支持实时特征工程和模型训练,特别适用于需要处理海量实时数据的机器学习工作流。 Iceberg作为数据湖,以支持其机器学习平台中的特征存储。Iceberg的分层结构、快照…...

QT交叉编译环境搭建(Cmake和qmake)
介绍一共有两种方法(基于qmake和cmake): 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别:CMake 和 qmake 都是自动化构建工具,用于简化构建过程,管理编译设置&…...

Turing Complete-成对的麻烦
这一关是4个输入,当输入中1的个数大于等于2时,输出1。 那么首先用个与门来检测4个输入中,1的个数是否大于等于2,当大于等于2时,至少会有一个与门输出1,所以再用两级或门讲6个与门的输出取或,得…...
寒假刷题Day20
一、80. 删除有序数组中的重复项 II class Solution { public:int removeDuplicates(vector<int>& nums) {int n nums.size();int stackSize 2;for(int i 2; i < n; i){if(nums[i] ! nums[stackSize - 2]){nums[stackSize] nums[i];}}return min(stackSize, …...

deepseek 本地化部署和小模型微调
安装ollama 因为本人gpu卡的机器系统是centos 7, 直接使用ollama会报 所以ollama使用镜像方式进行部署, 拉取镜像ollama/ollama 启动命令 docker run -d --privileged -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama 查看ollama 是否启动…...
【Java异步编程】基于任务类型创建不同的线程池
文章目录 一. 按照任务类型对线程池进行分类1. IO密集型任务的线程数2. CPU密集型任务的线程数3. 混合型任务的线程数 二. 线程数越多越好吗三. Redis 单线程的高效性 使用线程池的好处主要有以下三点: 降低资源消耗:线程是稀缺资源,如果无限…...
makailio-alias_db模块详解
ALIAS_DB 模块 作者 Daniel-Constantin Mierla micondagmail.com Elena-Ramona Modroiu ramonaasipto.com 编辑 Daniel-Constantin Mierla micondagmail.com 版权 © 2005 Voice Sistem SRL © 2008 asipto.com 目录 管理员指南 概述依赖 2.1 Kamailio 模块 2.2 外…...

文字显示省略号
多行文本溢出显示省略号...

[LeetCode] 字符串完整版 — 双指针法 | KMP
字符串 基础知识双指针法344# 反转字符串541# 反转字符串II54K 替换数字151# 反转字符串中的单词55K 右旋字符串 KMP 字符串匹配算法28# 找出字符串中第一个匹配项的下标#459 重复的子字符串 基础知识 字符串的结尾:空终止字符00 char* name "hello"; …...
从零开始部署Dify:后端与前端服务完整指南
从零开始部署Dify:后端与前端服务完整指南 一、环境准备1. 系统要求2. 项目结构 二、后端服务部署1. 中间件启动(Docker Compose)2. 后端环境配置3. 依赖安装与数据库迁移4. 服务启动 三、前端界面搭建1. 环境配置2. 服务启动 四、常见问题排…...
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 是一种简化 Spring 应用开发的框架,它提供了多种默认配置和方便的开发特性。在 Web 开发中,路径配置和请求的重定向/转发是常见操作。本文将详细介绍 Spring Boot 中的路径默认配置,并解释重定向和转发过程中存在的域对象。 一、…...

二叉树——429,515,116
今天继续做关于二叉树层序遍历的相关题目,一共有三道题,思路都借鉴于最基础的二叉树的层序遍历。 LeetCode429.N叉树的层序遍历 这道题不再是二叉树了,变成了N叉树,也就是该树每一个节点的子节点数量不确定,可能为2&a…...
Leetcode 3444. Minimum Increments for Target Multiples in an Array
Leetcode 3444. Minimum Increments for Target Multiples in an Array 1. 解题思路2. 代码实现 题目链接:3444. Minimum Increments for Target Multiples in an Array 1. 解题思路 这一题我的思路上就是一个深度优先遍历,考察target数组当中的每一个…...

分享半导体Fab 缺陷查看系统,平替klarity defect系统
分享半导体Fab 缺陷查看系统,平替klarity defect系统;开发了半年有余。 查看Defect Map,Defect image,分析Defect size,defect count trend. 不用再采用klarity defect系统(license 太贵) 也可以…...

Java基础——分层解耦——IOC和DI入门
目录 三层架构 Controller Service Dao 编辑 调用过程 面向接口编程 分层解耦 耦合 内聚 软件设计原则 控制反转 依赖注入 Bean对象 如何将类产生的对象交给IOC容器管理? 容器怎样才能提供依赖的bean对象呢? 三层架构 Controller 控制…...

DeepSeek-R1 本地部署教程(超简版)
文章目录 一、DeepSeek相关网站二、DeepSeek-R1硬件要求三、本地部署DeepSeek-R11. 安装Ollama1.1 Windows1.2 Linux1.3 macOS 2. 下载和运行DeepSeek模型3. 列出本地已下载的模型 四、Ollama命令大全五、常见问题解决附:DeepSeek模型资源 一、DeepSeek相关网站 官…...

Vue3学习笔记-模板语法和属性绑定-2
一、文本插值 使用{ {val}}放入变量,在JS代码中可以设置变量的值 <template><p>{{msg}}</p> </template> <script> export default {data(){return {msg: 文本插值}} } </script> 文本值可以是字符串,可以是布尔…...

csapp笔记3.6节——控制(1)
本节解决了x86-64如何实现条件语句、循环语句和分支语句的问题 条件码 除了整数寄存器外,cpu还维护着一组单个位的条件码寄存器,用来描述最近的算数和逻辑运算的某些属性。可检测这些寄存器来执行条件分支指令。 CF(Carry Flag)…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)
说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
Oracle查询表空间大小
1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
代码随想录刷题day30
1、零钱兑换II 给你一个整数数组 coins 表示不同面额的硬币,另给一个整数 amount 表示总金额。 请你计算并返回可以凑成总金额的硬币组合数。如果任何硬币组合都无法凑出总金额,返回 0 。 假设每一种面额的硬币有无限个。 题目数据保证结果符合 32 位带…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖
在Vuzix M400 AR智能眼镜的助力下,卢森堡罗伯特舒曼医院(the Robert Schuman Hospitals, HRS)凭借在无菌制剂生产流程中引入增强现实技术(AR)创新项目,荣获了2024年6月7日由卢森堡医院药剂师协会࿰…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...