网络编程-实现客户端通信

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/select.h>#define MAX_CLIENTS 2      // 最大客户端连接数
#define BUFFER_SIZE 1024   // 消息缓冲区大小int main(int argc, char *argv[]) {/* 参数校验 */if (argc != 2) {printf("用法: %s <端口号>\n", argv[0]);exit(1);}/* 创建服务器socket */// AF_INET: IPv4协议// SOCK_STREAM: 流式socket(TCP)int server_fd = socket(AF_INET, SOCK_STREAM, 0);if (server_fd < 0) {perror("socket创建失败");exit(1);}/* 配置服务器地址 */struct sockaddr_in addr = {.sin_family = AF_INET,                     // IPv4地址族.sin_port = htons(atoi(argv[1])),          // 端口号(主机字节序转网络字节序).sin_addr.s_addr = INADDR_ANY              // 监听所有本地接口};/* 绑定socket到指定地址 */if (bind(server_fd, (struct sockaddr*)&addr, sizeof(addr)) {perror("绑定失败");close(server_fd);exit(1);}/* 开始监听连接请求 */// 参数5: 等待连接队列的最大长度if (listen(server_fd, 5) < 0) {perror("监听失败");close(server_fd);exit(1);}printf("服务器已启动,监听端口: %s\n", argv[1]);/* 客户端管理数据结构 */int client_sockets[MAX_CLIENTS] = {0};  // 客户端socket数组char client_ids[MAX_CLIENTS] = {0};     // 客户端标识符('1'或'2')fd_set readfds;                         // 文件描述符集合int max_fd;                             // 最大文件描述符值/* 主事件循环 */while(1) {// 清空文件描述符集合FD_ZERO(&readfds);// 添加服务器socket到监听集合FD_SET(server_fd, &readfds);max_fd = server_fd;// 添加客户端socket到监听集合for(int i = 0; i < MAX_CLIENTS; i++) {if(client_sockets[i] > 0) {FD_SET(client_sockets[i], &readfds);if(client_sockets[i] > max_fd)max_fd = client_sockets[i];}}/* 使用select监听IO事件 */// 参数说明:// 1. max_fd+1: 最大文件描述符值+1// 2. &readfds: 读事件监听集合// 3. NULL: 不监听写事件// 4. NULL: 不监听异常事件// 5. NULL: 无限等待int activity = select(max_fd + 1, &readfds, NULL, NULL, NULL);if ((activity < 0) && (errno != EINTR)) {perror("select错误");}/* 处理新连接请求 */if (FD_ISSET(server_fd, &readfds)) {// 接受新连接int new_socket = accept(server_fd, NULL, NULL);if (new_socket < 0) {perror("接受连接失败");continue;}// 将新客户端添加到数组int added = 0;for(int i = 0; i < MAX_CLIENTS; i++) {if(client_sockets[i] == 0) {client_sockets[i] = new_socket;// 接收客户端标识符(阻塞式接收第一个字节)recv(new_socket, &client_ids[i], 1, 0);printf("客户端 %c 已连接\n", client_ids[i]);added = 1;break;}}if (!added) {printf("连接已满,拒绝新连接\n");close(new_socket);}}/* 处理客户端消息 */for(int i = 0; i < MAX_CLIENTS; i++) {int sd = client_sockets[i];if (sd > 0 && FD_ISSET(sd, &readfds)) {char buffer[BUFFER_SIZE] = {0};// 接收消息int valread = read(sd, buffer, BUFFER_SIZE);/* 处理断开连接 */if (valread == 0) {getpeername(sd, (struct sockaddr*)&addr, (socklen_t*)&addr);printf("客户端 %c 断开连接\n", client_ids[i]);close(sd);client_sockets[i] = 0;client_ids[i] = 0;}/* 转发消息 */else {printf("转发来自客户端 %c 的消息\n", client_ids[i]);// 遍历所有客户端进行转发for(int j = 0; j < MAX_CLIENTS; j++) {int dest = client_sockets[j];// 跳过自身和无效socketif (dest > 0 && client_ids[j] != client_ids[i]) {send(dest, buffer, strlen(buffer), 0);}}}}}}close(server_fd);return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <poll.h>#define BUFFER_SIZE 1024   // 输入缓冲区大小int main(int argc, char *argv[]) {/* 参数校验 */if (argc != 3) {printf("用法: %s <IP地址> <端口号>\n", argv[0]);exit(1);}/* 创建客户端socket */int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0) {perror("socket创建失败");exit(1);}/* 配置服务器地址 */struct sockaddr_in serv_addr = {.sin_family = AF_INET,.sin_port = htons(atoi(argv[2])),   // 端口号转换.sin_addr.s_addr = inet_addr(argv[1]) // IP地址转换};/* 建立连接 */if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {perror("连接失败");close(sock);exit(1);}/* 发送客户端标识符 */char client_id = '1';send(sock, &client_id, 1, 0);printf("已连接到服务器\n");/* 配置poll监听结构体 */struct pollfd fds[2] = {{.fd = STDIN_FILENO, .events = POLLIN},  // 监听标准输入{.fd = sock,         .events = POLLIN}   // 监听socket输入};/* 主循环 */while(1) {// 使用poll等待事件(无限等待)int ret = poll(fds, 2, -1);if (ret == -1) {perror("poll错误");break;}/* 处理键盘输入事件 */if (fds[0].revents & POLLIN) {char buffer[BUFFER_SIZE];// 安全获取输入(自动截断)if (fgets(buffer, BUFFER_SIZE, stdin) != NULL) {// 发送消息到服务器send(sock, buffer, strlen(buffer), 0);}}/* 处理服务器消息事件 */if (fds[1].revents & POLLIN) {char buffer[BUFFER_SIZE] = {0};int len = recv(sock, buffer, BUFFER_SIZE, 0);if (len > 0) {printf("收到消息: %s", buffer);} else if (len == 0) {printf("服务器断开连接\n");break;} else {perror("接收错误");break;}}}close(sock);return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>#define BUFFER_SIZE 1024// 全局socket描述符
int sock;
// 互斥锁(保护socket操作)
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;/* 发送线程函数 */
void* send_thread(void* arg) {while(1) {char buffer[BUFFER_SIZE];// 获取用户输入if (fgets(buffer, BUFFER_SIZE, stdin) != NULL) {// 加锁发送pthread_mutex_lock(&lock);send(sock, buffer, strlen(buffer), 0);pthread_mutex_unlock(&lock);}}return NULL;
}/* 接收线程函数 */
void* recv_thread(void* arg) {while(1) {char buffer[BUFFER_SIZE] = {0};int len;// 加锁接收pthread_mutex_lock(&lock);len = recv(sock, buffer, BUFFER_SIZE, 0);pthread_mutex_unlock(&lock);if (len > 0) {printf("收到消息: %s", buffer);} else if (len == 0) {printf("服务器断开连接\n");break;} else {perror("接收错误");break;}}return NULL;
}int main(int argc, char *argv[]) {/* 参数校验 */if (argc != 3) {printf("用法: %s <IP地址> <端口号>\n", argv[0]);exit(1);}/* 创建客户端socket */sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0) {perror("socket创建失败");exit(1);}/* 配置服务器地址 */struct sockaddr_in serv_addr = {.sin_family = AF_INET,.sin_port = htons(atoi(argv[2])),.sin_addr.s_addr = inet_addr(argv[1])};
/* 为服务器准备ip和port(提前)struct sockaddr_in addr = {0};addr.sin_family = AF_INET;addr.sin_port = htons(port);addr.sin_addr.s_addr = inet_addr("192.168.110.223");
*//* 建立连接 */if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {perror("连接失败");close(sock);exit(1);}/* 发送客户端标识符 */char client_id = '2';send(sock, &client_id, 1, 0);printf("已连接到服务器\n");/* 创建发送和接收线程 */pthread_t tid_send, tid_recv;pthread_create(&tid_send, NULL, send_thread, NULL);pthread_create(&tid_recv, NULL, recv_thread, NULL);/* 等待线程结束(实际不会执行到这里) */pthread_join(tid_send, NULL);pthread_join(tid_recv, NULL);close(sock);return 0;
}

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

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

相关文章

力扣100二刷——图论、回溯

第二次刷题不在idea写代码&#xff0c;而是直接在leetcode网站上写&#xff0c;“逼”自己掌握常用的函数。 标志掌握程度解释办法⭐Fully 完全掌握看到题目就有思路&#xff0c;编程也很流利⭐⭐Basically 基本掌握需要稍作思考&#xff0c;或者看到提示方法后能解答⭐⭐⭐Sl…

【大模型实战篇】多模态推理模型Skywork-R1V

1. 背景介绍 近期昆仑万维开源的Skywork R1V模型&#xff0c;是基于InternViT-6B-448px-V2_5以及deepseek-ai/DeepSeek-R1-Distill-Qwen-32B 通过强化学习得到。当然语言模型也可以切换成QwQ-32B。因此该模型最终的参数量大小为38B。 该模型具备多模态推理能力&#xf…

识别并脱敏上传到deepseek/chatgpt的文本文件中的护照信息

本文将介绍一种简单高效的方法解决用户在上传文件到DeepSeek、ChatGPT&#xff0c;文心一言&#xff0c;AI等大语言模型平台过程中的护照号识别和脱敏问题。 DeepSeek、ChatGPT&#xff0c;Qwen&#xff0c;Claude等AI平台工具快速的被接受和使用&#xff0c;用户每天上传的文…

数据驱动进化:AI Agent如何重构手机交互范式?

如果说AIGC拉开了内容生成的序幕&#xff0c;那么AI Agent则标志着AI从“工具”向“助手”的跨越式进化。它不再是简单的问答机器&#xff0c;而是一个能够感知环境、规划任务并自主执行的智能体&#xff0c;更像是虚拟世界中的“全能员工”。 正如行业所热议的&#xff1a;“大…

【AI News | 20250319】每日AI进展

AI Repos 1、XianyuAutoAgent 实现了 24 小时自动化值守的 AI 智能客服系统&#xff0c;支持多专家协同决策、智能议价和上下文感知对话&#xff0c;让我们店铺管理更轻松。主要功能&#xff1a; 智能对话引擎&#xff0c;支持上下文感知和专家路由阶梯降价策略&#xff0c;自…

nginx中间件部署

中间件部署流程 ~高级权限账户安装必要的插件 -> 普通权限账户安装所需要的服务 -> 高级权限账户开启并设置开机自启所安装的服务 -> iptables放行所需要的服务 普通权限账户安装NGINX中间件 1、拥有高级权限的账户安装必要的插件 sudo yum install -y gcc-c make…

C语言自定义类型【结构体】详解,【结构体内存怎么计算】 详解 【热门考点】:结构体内存对齐

引言 详细讲解什么是结构体&#xff0c;结构体的运用&#xff0c; 详细介绍了结构体在内存中占几个字节的计算。 【热门考点】&#xff1a;结构体内存对齐 介绍了&#xff1a;结构体传参 一、什么是结构体&#xff1f; 结构是⼀些值的集合&#xff0c;这些值称为成员变量。结构…

前端应用更新通知机制全解析:构建智能化版本更新策略

引言&#xff1a;数字时代的更新挑战 在持续交付的现代软件开发模式下&#xff0c;前端应用平均每周产生2-3次版本迭代。但据Google研究报告显示&#xff0c;38%的用户在遇到功能异常时仍在使用过期版本的应用。如何优雅地实现版本更新通知&#xff0c;已成为提升用户体验的关…

Apache DolphinScheduler:一个可视化大数据工作流调度平台

Apache DolphinScheduler&#xff08;海豚调度&#xff09;是一个分布式易扩展的可视化工作流任务调度开源系统&#xff0c;适用于企业级场景&#xff0c;提供了一个可视化操作任务、工作流和全生命周期数据处理过程的解决方案。 Apache DolphinScheduler 旨在解决复杂的大数据…

[蓝桥杯 2023 省 B] 飞机降落

[蓝桥杯 2023 省 B] 飞机降落 题目描述 N N N 架飞机准备降落到某个只有一条跑道的机场。其中第 i i i 架飞机在 T i T_{i} Ti​ 时刻到达机场上空&#xff0c;到达时它的剩余油料还可以继续盘旋 D i D_{i} Di​ 个单位时间&#xff0c;即它最早可以于 T i T_{i} Ti​ 时刻…

使用Trae 生成的React版的贪吃蛇

使用Trae 生成的React版的贪吃蛇 首先你想用这个贪吃蛇&#xff0c;你需要先安装Trae Trae 官方地址 他有两种模式 chat builder 我使用的是builder模式,虽然是Alpha.还是可以用。 接下来就是按着需求傻瓜式的操作生成代码 他生成的代码不完全正确&#xff0c;比如没有引入…

AI大模型:(一)1.大模型的发展与局限

说起AI大模型不得不说下机器学习的发展史&#xff0c;机器学习包括传统机器学习、深度学习&#xff0c;而大模型&#xff08;Large Models&#xff09;属于机器学习中的深度学习&#xff08;Deep Learning&#xff09;领域&#xff0c;具体来说&#xff0c;它们通常基于神经网络…

rust学习笔记17-异常处理

今天聊聊rust中异常错误处理 1. 基础类型&#xff1a;Result 和 Option&#xff0c;之前判断空指针就用到过 Option<T> 用途&#xff1a;表示值可能存在&#xff08;Some(T)&#xff09;或不存在&#xff08;None&#xff09;&#xff0c;适用于无需错误信息的场景。 f…

Python:单继承方法的重写

继承&#xff1a;让类和类之间转变为父子关系&#xff0c;子类默认继承父类的属性和方法 单继承&#xff1a; class Person:def eat(self):print("eat")def sing(self):print("sing") class Girl(Person):pass#占位符&#xff0c;代码里面类下面不写任何东…

记录一下aes加密与解密

该文章只做拓展后续会更新&#xff1b;如有出错请指出 首先需要先引入相关依赖 crypto-js 然后直接开始存储 export function aesEncrypt(message: string, key: string) {return aes.encrypt(message, key).toString(); } 之后是解密方式 function decrypt(content: any, key…

[免费]直接整篇翻译pdf工具-支持多种语言

<闲来没事写篇博客填补中文知识库漏洞> 如题&#xff0c;[免费][本地]工具基于开源仓库&#xff1a; 工具 是python&#xff01;太好了&#xff0c;所以各个平台都可以&#xff0c;我这里基于windows. 1. 先把github代码下载下来&#xff1a; git clone https://githu…

UI设计中的用户反馈机制:提升交互体验的关键

hello宝子们...我们是艾斯视觉擅长ui设计和前端数字孪生、大数据、三维建模、三维动画10年经验!希望我的分享能帮助到您!如需帮助可以评论关注私信我们一起探讨!致敬感谢感恩! 在数字化产品泛滥的今天&#xff0c;用户与界面的每一次交互都在无形中塑造着他们对产品的认知。一个…

Hessian 矩阵是什么

Hessian 矩阵是什么 目录 Hessian 矩阵是什么Hessian 矩阵的性质及举例说明**1. 对称性****2. 正定性决定极值类型****特征值为 2(正),因此原点 ( 0 , 0 ) (0, 0) (0,0) 是极小值点。****3. 牛顿法中的应用****4. 特征值与曲率方向****5. 机器学习中的实际意义**一、定义与…

Nginx 代理访问一个 Web 界面时缺少内容

1. 资源路径问题 Web 页面中的静态资源&#xff08;如图片、CSS、JavaScript 文件&#xff09;可能使用了相对路径或绝对路径&#xff0c;而这些路径在代理后无法正确加载。 解决方法&#xff1a; 检查资源路径&#xff1a;打开浏览器的开发者工具&#xff08;按 F12&#xf…

GPU视频编解码:Jetson VPI+multimedia_api视频编解码入门(一)

目录 一.Pipline与工具栈 二.硬件设备概况 三.GPU视频编解码框架 四.VPI编译使用实例 五. jetson_multimedia_api编译使用实例 一.Pipline与工具栈 二.硬件设备概况 三.GPU视频编解码框架 jetson设备目前不支持VPF框架&#xff0c;关于VPF的使用我在下节PC段使用X86进行安…