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

Next 10 TCP并发,数据库

作业:

server 服务端 epoll #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <netinet/in.h> #include <netinet/ip.h> #include <arpa/inet.h> #include <time.h> #include <sys/epoll.h> typedef struct sockaddr *(SA); int add_fd(int epfd, int fd) { struct epoll_event ev = {0}; ev.events = EPOLLIN; ev.data.fd = fd; int ret = epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev); if (-1 == ret) { perror("add_fd"); return ret; } return 0; } int main(int argc, char **argv) { // 1. internet , udp, 默认协议 int udpfd = socket(AF_INET, SOCK_DGRAM, 0); if (-1 == udpfd) { perror("socket"); return 1; } // 2. 给套接字 绑定ip ,端口号 // man 7 ip 查询 ipv4 的地址结构体 struct sockaddr_in ser, cli; // 服务器的地址结构体, 客户端的地址结构体 bzero(&ser, sizeof(ser)); bzero(&cli, sizeof(cli)); ser.sin_family = AF_INET; // ipv4 ser.sin_port = htons(50000); // host to net short 小端转大端 ser.sin_addr.s_addr = INADDR_ANY; int ret = bind(udpfd, (SA)&ser, sizeof(ser)); if (-1 == ret) { perror("bind"); return 1; } socklen_t len = sizeof(cli); char buf[1024] = {0}; recvfrom(udpfd, buf, sizeof(buf), 0, (SA)&cli, &len); // ep1 create set struct epoll_event rev[2]; int epfd = epoll_create(2); if (-1 == epfd) { perror("epoll_creaete"); return 1; } // ep2 add_fd add_fd(epfd, udpfd); add_fd(epfd, 0); while (1) { bzero(buf, sizeof(buf)); int ep_ret = epoll_wait(epfd, rev, 2, -1); int i = 0; for (i = 0; i < ep_ret; i++) { if (0 == rev[i].data.fd) // 标准输入可以读取 { printf("to cli:"); fgets(buf, sizeof(buf), stdin); sendto(udpfd, buf, sizeof(buf), 0, (SA)&cli, len); if (0 == strcmp(buf, "#quit\n")) { return 0; } } else { recvfrom(udpfd, buf, sizeof(buf), 0, NULL, NULL); if (0 == strcmp(buf, "#quit\n")) { return 0; } printf("from cli:%s", buf); fflush(stdout); } } } return 0; }

一、TCP并发进程

/** * @file 01ser.c 进程版本的并发 tcp 服务器 1 .僵尸进程的回收 2. 文件描述符的回收 listfd conn ,对于父子进程的差异 * @author yashiro (rage_yas@hotmail.com) * @brief * @version 0.1 * @date 2026-03-09 * * @copyright Copyright (c) 2026 * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <time.h> #include <sys/wait.h> #include <signal.h> typedef struct sockaddr *(SA); void handle(int num) { wait(NULL); } int main(int argc, char **argv) { signal(SIGCHLD, handle); // 1 打开网络设备,获得文件描述(套接字) // 监听套接字 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 = INADDR_ANY; // 2 给套接字绑定 ip +port ,方便客户端找到服务器 int ret = bind(listfd, (SA)&ser, sizeof(ser)); if (-1 == ret) { perror("bind"); return 1; } // 3 进入监听状态 (套接字进入可以被链接的状态) // 参数2 ,进行三次握手的排队数 listen(listfd, 3); socklen_t len = sizeof(cli); while (1) // 三次握手多个客户端 { // 4 建立链接 (触发三次握手) // 通信套接字,表示从服务端来看,conn 是客户端的套接字 int conn = accept(listfd, (SA)&cli, &len); if (-1 == conn) { perror("accept"); close(conn); continue; } pid_t pid = fork(); if (pid > 0) { close(conn); // wait(NULL); } else if (0 == pid) { close(listfd); while (1) // 与客户端的多次收发 { char buf[512] = {0}; // 5 接收数据 // 返回值 >0 实际收到的字节数 ==0 对方断开 -1 错误 int rd_ret = recv(conn, buf, sizeof(buf), 0); if (rd_ret <= 0) { printf("cli offline\n"); exit(0); } // 5.5 处理数据 printf("cli:%s\n", buf); time_t tm; time(&tm); sprintf(buf, "%s %s", buf, ctime(&tm)); // 6 发送数据 send(conn, buf, strlen(buf), 0); } } else { perror("fork"); continue; } } // 7 断开链接 close(listfd); return 0; }

二、tcp 线程

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> #include <netinet/in.h> #include <netinet/ip.h> #include <time.h> #include <pthread.h> #include <semaphore.h> sem_t sem_arg; typedef struct sockaddr*(SA); void* th(void* arg) { int conn = *(int*)arg; sem_post(&sem_arg); // 分离属性, 当线程结束后,栈区自动由系统回收 pthread_detach(pthread_self()); while (1) { char buf[512] = {0}; // 5 接收数据 // 返回值 >0 实际收到的字节数 ==0 对方断开 -1 错误 int rd_ret = recv(conn, buf, sizeof(buf), 0); if (rd_ret <= 0) { printf("cli offline\n"); close(conn); break; } // 5.5 处理数据 printf("cli:%s\n", buf); time_t tm; time(&tm); sprintf(buf, "%s %s", buf, ctime(&tm)); // 6 发送数据 send(conn, buf, strlen(buf), 0); } return NULL; } int main(int argc, char** argv) { // 1 打开网络设备,获得文件描述(套接字) // 监听套接字 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 = INADDR_ANY; // 2 给套接字绑定 ip +port ,方便客户端找到服务器 int ret = bind(listfd, (SA)&ser, sizeof(ser)); if (-1 == ret) { perror("bind"); return 1; } // 3 进入监听状态 (套接字进入可以被链接的状态) // 参数2 ,进行三次握手的排队数 listen(listfd, 3); socklen_t len = sizeof(cli); sem_init(&sem_arg, 0, 0); while (1) { // 4 建立链接 (触发三次握手) // 通信套接字,表示从服务端来看,conn 是客户端的套接字 int conn = accept(listfd, (SA)&cli, &len); if (-1 == conn) { perror("accept"); close(conn); continue; } pthread_t tid; pthread_create(&tid, NULL, th, &conn); // usleep(1000*20); //20 ms // pthread_join(); // 确保 conn 参数一定在th现存中,被保存下来 sem_wait(&sem_arg); } sem_destroy(&sem_arg); // 7 断开链接 close(listfd); return 0; }

三、数据库

数据库,是一个应用程序。可以对数据进行存储,并进行管理和统计的程序。多和服务器搭配使用

数据库中,数据是以表的形式组织在一起。一张表可以分为多个记录(行),一条记录可以分为多个字段(列)。

SQL struct query language 关系型数据库 非关系 芒果db

ddl data defination language 建表

dml 新增 修改 删除一行 data modifty

dql 查询 data query language 查询 select

2、名词:

DB 数据库 select update database

DBMS 数据库管理系统

MIS 管理信息系统

OA 办公自动化

3、嵌入式数据库:

sqlite www.sqlite.org www.kernal.org

GNU

特点:

1、开源 C语言开发

2、代码量少1万行左右,,总大小10M以内

3、绿色软件无需安装4、文件型数据库,可以移动。

5、数据容量最大2T

.database列出当前库和系统中那个文件在关联

.tables列出当期数据库中的所有表

.schemaXXX列出当前指定的xxx表结构

.headers on查询数据的时候显示列名

2、标准SQL语句:===》通用语法在其他平台可以直接使用。

struct query language;

注意:所有的sql语句都以;结尾。

创建一个表:ddl

create table 表名(表字段1,表字段2,...);

eg: create table user(id,name,age); char

注意:以上表的表字段,支持如下数据类型。int text real blob

默认是text类型。char

create table 表名(表字段 类型,表字段 类型,。。。);

eg: create table user(id int ,name char,age int);

删除一个表:

drop table 表名;

eg:drop table user;

向表中增加数据:insert into表名(字段名称)values(值名称);

eg: insert into user (id,age) values (1,10);

insert into user values(3,"wang",11);

insert into user (age) values ( 12);

insert into user1 values (2,'张三',23,datetime('now"'+8hours'));时间列

select datetime('now','+8 hours','-1 year');

CREATE TABLE user3(id INTEGER PRIMARY KEY ASC,name char,age int,dt datetime);

sqlite> insert into user3 (NULL,'李四',23,datetime('now','+ 8 hours');自动增长列

PRIMARY KEY主键,唯一性,如果使用主键作为搜索条件,比普通字段块。

查询表中的数据:

select 列名 from 表名 条件;

* 代表所有的列

select id,name from user where not age <30 ;

'%':0到任意多个任意字符;

'_':一个任意字符。

升序:select * from user order by id;

降序:select *from user order by id desc;

有限:select * from user limit 3;

修改表中数据:

update 表名 set 表字段 = 值满足条件:

update user set id = 2 where name = "li" or name ="zhao";

删除表中数据delete from 表名 满足条件:

delete from user where id =10;

数据库的导入导出

1、数据的导出:sqlite3 xxx.db.dump > xxx.sq1

//将数据库名称为xxx的数据库整体导出到脚本中。

2、数据的导入:sqlite3 xxx.db < xxx.sq1

数据库代码

1.打开数据库:

sqlite3_openint sqlite3_open(char * path,sqlite3 ** db);

功能:打开指定path路径+文件名称的数据库,并将打开的地址指向db变量的句柄。

参数:path要打开的数据库路径+名称db要打开的数据库地址指针

返回值:成功0;失败-1;

2.关闭数据库:sqlite3_closeint sqlite3_close(sqlite3 *db);

功能:关闭指定的数据库

参数:要关闭的数据库地址

返回值:成功0;失败-1;

3执行sql语句

int sqlite3_exec(sqlite3 *db,char *sql,callback fun,void *arg,char errmsg);

功能:在db数据库上执行sq1非查询语句。并将结果返回。

参数:db要执行sql的数据库sq1要执行的非查询sql语句。

fun如果该函数要执行查询语句,则该回调函数用来回收查询的结果。

arg回调函数的参数,如果没有回调函数则该参数为NULL:

errmsg执行过程中的错误信息。

返回值:执行成功0;失败非0。

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sqlite3.h> int main(int argc, char **argv) { sqlite3 *db = NULL; // 1 打开数据库,获得数据的句柄(相当于linux 中的文件描述符) int ret = sqlite3_open("aaa.db", &db); if (SQLITE_OK != ret) { fprintf(stderr, "open db error %s\n", sqlite3_errstr(ret)); sqlite3_close(db); return 1; } char *errmsg = NULL; //需要执行的sql语句, 不要执行查询语句(select), char sql_cmd[512] = "insert into user values(7,'帅哥',20)"; // 2 执行sql语句(对数据库的读写) ret = sqlite3_exec(db, sql_cmd, NULL, NULL, &errmsg); if (SQLITE_OK != ret) { fprintf(stderr, "sqlite3_exec sql_cmd:[%s] ,%s\n", sql_cmd, errmsg); sqlite3_free(errmsg); sqlite3_close(db); return 1; } // 3. 关闭数据 释放资源 sqlite3_close(db); return 0; }
http://www.jsqmd.com/news/458204/

相关文章:

  • 排序算法的终极博弈:从复杂度推导到工程选型实战
  • keil破解时报TOOLS.INI_TOOLCHAIN NOT INSTALLED解决
  • 全维度测评主流视频会议软件,精选高效协作之选
  • 【稳健之道】第二篇:Mock 的艺术 —— 隔离外部世界的“混沌”
  • Python部署卡壳工业MES?Java+YOLOv11+Spring Boot 3.4完美对接PLC!
  • 搭了个AI快讯自动化系统,每天花15分钟看全球AI动态,竟遭Claude封号了
  • MetaNovas两轮融资,AI改写材料研发格局
  • 讲讲2026年学校制冷设备一站式采购批发,如何选择靠谱厂家 - 工业推荐榜
  • 一文吃透AI合规:算法备案、大模型备案、大模型登记!
  • 口碑好的中央空调厂家排名,浙江省有哪些值得选 - mypinpai
  • KIHU快狐|75寸落地全面屏广告机高清展示教学会议信息发布终端
  • 大数据基于Python的大模型岗位人才需求可视化分析
  • 什么是 Java 的 Timer?
  • 写给技术管理者的低代码手册系列文章(8)——第二部分:低代码的概念、价值与发展现状(第四章)
  • 别等着被优化:DevOps 工程师转型 AI 工程师,为什么反而更有优势?
  • 上海理查德米勒机芯异响、震动问题测评解析 - 时光修表匠
  • 2026年3月安徽四柱液压机/压力机/折弯机/液压机/冲床公司推荐:行业变局下的选型逻辑与头部企业解码 - 2026年企业推荐榜
  • 永磁同步电机 滑膜观测器参数识别Matlab/simulink仿真 包括转动惯量 阻尼系数 负...
  • 2026澳洲最好的证券公司求职笔试辅导在哪里:独家面经(必看) - Matthewmx
  • 成套电力接地线,一站式配齐施工检修更高效 - 非研科技
  • 政府创新采购数据库(2016-2024)
  • 2026陕西西安AI人工智能培训+视频剪辑培训哪家强?达内优创综合实力稳居第一(附数据分析/Java/云计算运维课程) - 深度智识库
  • 天虹提货券回收避坑指南:教你快速辨别正规平台 - 可可收
  • 直流变频冷干机工厂
  • HoRain云--二叉树遍历全解析:数据结构核心指南
  • 2026年热门的氨基酸洗面奶厂家推荐:氨基酸洗面奶实力工厂推荐 - 品牌宣传支持者
  • 苹果CMSV10 花心视频二开模板 视频网站源码可封装双端 APP-ym7K
  • 太强了!Python+Excel真的是神仙组合,值得你通宵看完!
  • 如何实现OpenClaw与飞书的更复杂交互,比如多轮对话或自定义命令
  • 邦定板评测排行 猎板高频混压技术领先