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

TCP服务器与客户端搭建

一、思维导图

二、给代码添加链表

        【server.c】

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;enum Type{TYPE_REGIST,TYPE_LOGIN
};typedef struct Pack{int size;enum Type type;char buf[2048];int count;
}pack_t;/*
typedef struct user_info{union Data{struct user_info* tail;char ui[20];}data;struct user_info* next;struct user_info* prev;
}UserInfo;UserInfo* create_node(){UserInfo* node = malloc(sizeof(UserInfo));node->next = NULL;node->prev = NULL;node->data.tail = node;return node;
}
*///从pack协议包中解析数据
void read_pack(pack_t* pack)
{char* buf = pack->buf;//记录buf已经读取的字节个数,方便定位到最靠前的未读取的位置int readed_size = 0;while(1){//将buf中最靠前未读取的2个字节,当作short读取,并赋值给data_sizeshort data_size = *(short*)(buf + readed_size);if(data_size == 0){printf("数据解析完毕\n");break;}//因为已经读取了2个字节,readed_size要自增2字节readed_size += 2;//准备一个大小为data_size+1的字符数组,用来接收数据char temp[data_size + 1];//初始化该数组memset(temp, 0, data_size+1);memcpy(temp, buf + readed_size, data_size);readed_size += data_size;printf("temp = %s\n", temp);}
}int main(int argc, const char* argv[])
{if(argc != 2){printf("请输入端口号!\n");return 1;}//将字符串转换成int类型portint port = atoi(argv[1]);//创建服务器套接字int server = socket(AF_INET, SOCK_STREAM, 0);//准备网络地址结构体: struct sockaddr_inaddr_in_t addr = {0};addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr("0.0.0.0");//为套接字绑定ip和portif(bind(server, (addr_t*)&addr, sizeof(addr)) == -1){perror("bind()");return 1;}//监听listen(server, 10);//接收客户端的连接addr_in_t client_addr = {0};int client_addr_len = sizeof(client_addr);int client = accept(server, (addr_t*)&client_addr, &client_addr_len);if(client != -1){printf("=== 客户端连接 ===\n");}//读取客户端发来的消息while(1){int pack_size = 0;int res = read(client, &pack_size, 4);if(res == 0){printf("=== 客户端断开连接 === \n");return 0;}//当前的 pack_size = 4(pack.size大小) + 4(pack.type大小) + buf大小pack_t pack = {0};read(client, (char*)&pack+4, pack_size-4);pack.size = pack_size;//解析协议包的所有数据read_pack(&pack);}return 0;
}

        【client.c】

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <fcntl.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>typedef struct sockaddr_in addr_in_t;
typedef struct sockaddr addr_t;enum Type{TYPE_REGIST,TYPE_LOGIN
};typedef struct Pack{int size; //记录整个协议包实际大小(定长部分,占4个字节)enum Type type; //定长部分,占4个字节char buf[2048]; //变长部分,占count个字节int count; //记录指针偏移量,即buf使用了多少个字节
}pack_t;/*
typedef struct user_info{union Data{struct user_info* tail;char ui[20];}data;struct user_info* next;struct user_info* prev;
}UserInfo;UserInfo* create_node(){UserInfo* node = malloc(sizeof(UserInfo));node->next = NULL;node->prev = NULL;node->data.tail = node;return node;
}
*/void append(pack_t* pack, const char* data)
{char* buf = pack->buf;int len = strlen(data);//将buf的前2个字节当作short来存储数据len*(short*)(buf + pack->count) = len;pack->count += 2;memcpy(buf + pack->count, data, len);pack->count += len;pack->size = pack->count + 8;
}int main(int argc, const char* argv[])
{if(argc != 2){printf("请输入端口号!\n");return 1;}//将字符串转换成int类型portint port = atoi(argv[1]);int client = socket(AF_INET, SOCK_STREAM, 0);addr_in_t addr = {0};addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr("192.168.126.155");if(connect(client, (addr_t*)&addr, sizeof(addr)) == -1){perror("connect()");return 1;}while(1){pack_t pack = {0};pack.type=TYPE_LOGIN;char name[20] = "";char pwd[20] = "";printf("请输入账号:");scanf("%20s", name);while(getchar() != 10);printf("请输入密码:");scanf("%20s", pwd);while(getchar() != 10);//前2个字节记录数据长度n,紧接着的n个字节记录数据本身//将name和pwd存入pack.buf中(即将name和pwd按照既定格式添加进协议包))append(&pack, name);append(&pack, pwd);//协议包总共占据 pack.count + 4 字节//pack.count 的长度,根据name和pwd的长度动态决定write(client, &pack, pack.size);}return 0;
}

相关文章:

TCP服务器与客户端搭建

一、思维导图 二、给代码添加链表 【server.c】 #include <stdio.h> #include <sys/socket.h> #include <sys/types.h> #include <fcntl.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #include <string.…...

PDF 文件的安全功能概述

由于安全问题始终存在&#xff0c;我们希望重点介绍 PDF 文件格式提供的一些安全功能。如果您希望控制或限制用户可以执行的操作&#xff0c;这些功能可以启用。本文将介绍可以阻止哪些类型的操作&#xff0c;以及可以实施哪些不同的身份验证技术来提高 PDF 的安全性。 可以控制…...

在Linux上部署Jenkins的详细指南

引言 在当今快速迭代的软件开发环境中&#xff0c;持续集成和持续交付&#xff08;CI/CD&#xff09;变得越来越重要。Jenkins作为一个开源自动化服务器&#xff0c;能够帮助开发者更高效地进行代码集成、测试和部署。本文将详细介绍如何在Linux系统上安装和配置Jenkins。 准…...

碳纤维复合材料制造的六西格玛管理实践:破解高端制造良率困局的实战密码

碳纤维复合材料制造的六西格玛管理实践&#xff1a;破解高端制造良率困局的实战密码 在全球碳中和与高端制造升级的双重驱动下&#xff0c;碳纤维复合材料行业正经历前爆发式增长。航空航天、新能源汽车、风电叶片等领域对碳纤维产品的性能稳定性提出近乎苛刻的要求&#xff0…...

Day83:图形的绘制

Python 提供了多种绘图工具,其中最常用的是 Turtle(海龟绘图)和 Matplotlib(数据可视化)。今天,我们主要介绍 Turtle,它可以轻松绘制各种几何图形、艺术图案和动画。 1. Turtle 库简介 Turtle 是 Python 内置的绘图工具,主要用于教学、趣味绘画和简单图形的创建。 基…...

C# Dll嵌入到.exe

将dll属性作为 嵌入的资源 修改引用属性为不复制 增加dll识别来源 AppDomain.CurrentDomain.AssemblyResolve new ResolveEventHandler(CurrentDomain_AssemblyResolve);private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, Reso…...

o3-mini、Gemini 2 Flash、Sonnet 3.5 与 DeepSeek 在 Cursor 上的对决

最新的 OpenAI 模型 o3-mini 已于 1 月 31 日&#xff08;星期五&#xff09;发布&#xff0c;并已在 Cursor 上架。不久后&#xff0c;Gemini 2 Flash 也会陆续登场。 上周&#xff0c;对 DeepSeek V3、DeepSeek R1 以及 Claude 3.5 Sonnet 做过类似测试。那次测试结果显示&am…...

如何在Vscode中接入Deepseek

一、获取Deepseek APIKEY 首先&#xff0c;登录Deepseek官网的开放平台&#xff1a;DeepSeek 选择API开放平台&#xff0c;然后登录Deepseek后台。 点击左侧菜单栏“API keys”&#xff0c;并创建API key。 需要注意的是&#xff0c;生成API key复制保存到本地&#xff0c;丢失…...

6 maven工具的使用、maven项目中使用日志

文章目录 前言一、maven&#xff1a;一款管理和构建java项目的工具1 基本概念2 maven的安装与配置&#xff08;1&#xff09;maven的安装&#xff08;2&#xff09;IDEA集成Maven配置当前项目工程设置 maven全局设置 &#xff08;3&#xff09;创建一个maven项目 3 pom.xml文件…...

Day82:创建图形界面(GUI)

在 Python 中,我们可以使用 Tkinter(标准 GUI 库)来创建图形用户界面(GUI)。Tkinter 提供了一系列工具和控件,使开发者可以轻松地创建窗口、按钮、输入框等界面组件。 1. Tkinter 简介 Tkinter 是 Python 内置的 GUI 库,使用它可以创建窗口应用程序,而无需安装额外的库…...

字节跳动大模型应用 Go 开发框架 —— Eino 实践

前言 开发基于大模型的软件应用&#xff0c;就像指挥一支足球队&#xff1a;组件是能力各异的队员&#xff0c;编排是灵活多变的战术&#xff0c;数据是流转的足球。Eino 是字节跳动开源的大模型应用开发框架&#xff0c;拥有稳定的内核&#xff0c;灵活的扩展性&#xff0c;完…...

【Golang学习之旅】Go + MySQL 数据库操作详解

文章目录 前言1. GORM简介2. 安装GORM并连接MySQL2.1 安装GORM和MySQL驱动2.2 连接MySQL 3. GORM数据模型&#xff08;Model&#xff09;3.1 定义User结构体3.2 自动迁移&#xff08;AutoMigrate&#xff09; 4. GORM CRUD 操作4.1 插入数据&#xff08;Create&#xff09;4.2 …...

Http 的响应码有哪些? 分别代表的是什么?

HTTP 状态码分为多个类别&#xff0c;下面是常见的 HTTP 状态码及其含义&#xff0c;包括 3xx 重定向状态码的详细区别&#xff1a; &#x1f4cc; HTTP 状态码分类 分类状态码范围说明1xx100-199信息性状态码&#xff0c;表示请求已被接收&#xff0c;继续处理2xx200-299成功…...

深入解析 Linux 系统中 Cron 定时任务的配置与管理

在 Linux 和类 Unix 系统中&#xff0c;cron 是一个非常强大的工具&#xff0c;用于定时执行各种任务&#xff0c;例如自动备份、定时运行脚本和定期清理日志文件。通过合理配置 cron&#xff0c;你可以让很多系统维护任务自动化&#xff0c;从而减轻日常管理的压力。而 cronta…...

关于 IoT DC3 中设备(Device)的理解

在物联网系统中&#xff0c;设备&#xff08;Device&#xff09;是一个非常宽泛的概念&#xff0c;它可以指代任何能够接入系统并进行数据交互的实体。包括但不限于手机、电脑、服务器、网关、硬件设备甚至是某些软件程序等所有能接入到该平台的媒介。 内容 定义 目的 示例 …...

golang 版 E签宝请求签名鉴权方式

E签宝 请求签名鉴权方式说明 package utilsimport ("crypto/hmac""crypto/md5""crypto/sha256""encoding/base64""fmt""github.com/gogf/gf/v2/util/gconv" )type Sign struct {secret string }func NewSign(sec…...

QTreeView和QTableView单元格添加超链接

QTreeView和QTableView单元格添加超链接的方法类似,本文仅以QTreeView为例。 在QTableView仿Excel表头排序和筛选中已经实现了超链接的添加,但是需要借助delegate,这里介绍一种更简单的方式,无需借助delegate。 一.效果 二.实现 QHTreeView.h #ifndef QHTREEVIEW_H #def…...

【WB 深度学习实验管理】使用 PyTorch Lightning 实现高效的图像分类实验跟踪

本文使用到的 Jupyter Notebook 可在GitHub仓库002文件夹找到&#xff0c;别忘了给仓库点个小心心~~~ https://github.com/LFF8888/FF-Studio-Resources 在机器学习项目中&#xff0c;实验跟踪和结果可视化是至关重要的环节。无论是调整超参数、优化模型架构&#xff0c;还是监…...

SSM开发(十一) mybatis关联关系多表查询(嵌套查询,举例说明)

目录 一、背景介绍 二、一对一查询(嵌套查询) 三、一对多查询(嵌套查询) 四、嵌套查询效率评估 注:关联查询则是指在一个查询中涉及到多个表的联合查询 一、背景介绍 当对数据库的操作涉及到多张表,这在面向对象语言如Java中就涉及到了对象与对象之间的关联关系。针对多…...

The Simulation技术浅析(六):机器学习

机器学习(Machine Learning)是模拟技术(The Simulation)的重要组成部分,通过从数据中自动学习规律和模式,机器学习能够提升模拟系统的智能化水平,增强其预测、决策和优化能力。 一、监督学习(Supervised Learning) 1. 基本原理 监督学习是指利用标注数据(即输入数…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

基于服务器使用 apt 安装、配置 Nginx

&#x1f9fe; 一、查看可安装的 Nginx 版本 首先&#xff0c;你可以运行以下命令查看可用版本&#xff1a; apt-cache madison nginx-core输出示例&#xff1a; nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...