C语言多人聊天室 ---chat(客户端聊天)

news2025/2/26 14:16:28

head.h

#ifndef __HEAD_H
#define __HEAD_H

// 常用头文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 网络编程涉及的头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>

#include <sys/types.h>

// 本机字节序和网络字节序转换相关函数的头文件
#include <arpa/inet.h>

// 关闭套接字用close函数需要的头文件
#include <unistd.h>

//线程相关的函数头, mutex相关的函数
#include <pthread.h>

// 类型重命名:地址结构体的规范
typedef struct sockaddr SockAddr;

// 地址结构体的规范的实现结构体
typedef struct sockaddr_in SockAddrIn;


// if_nametoindex
#include <net/if.h>

#include <sys/select.h>
#include <sys/time.h>

// JSON字符串的封装
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 文件操作需要的头文件
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <fcntl.h>
#include <mysql/mysql.h>

// selet
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>

// 定义外部变量
//int sockfdNUM[10] = {0};

#endif

p_char.h

#ifndef _P_CHAT_H
#define _P_CHAT_H

#define BUF_SIZE 1024

#include "head.h"

// 错误处理函数,用于输出错误信息并终止程序
void error_handling(const char *message);

#endif

p_chat.c

#include "p_chat.h"

// 私聊接收任务函数
void *s_private_chat(void *arg)
{
    // 1.获取客户端套接字
    int sock = *(int *)arg;

    char buf[1024] = {0};
    while (1)
    {
        scanf("%s", buf);
        send(sock, buf, strlen(buf), 0);
        if (strcmp(buf, "quit") == 0)
        {
            break;
        }
        memset(buf, 0, sizeof(buf));
    }

    // 关闭服务端套接字
    close(sock);
    exit(0); // 结束整个线程
}

void *r_private_chat(void *arg)
{
    // 1.获取客户端套接字
    int sock = *(int *)arg;

    char buf[1024] = {0};
    while (1)
    {
        recv(sock, buf, sizeof(buf), 0);
        printf("%s\n", buf);
        memset(buf, 0, sizeof(buf));
    }

    // 关闭服务端套接字
    close(sock);
}

// 客户端
int main(int argc, char const *argv[])
{
    // 创建线程id
    pthread_t tid1;
    pthread_t tid2;

    // 1.创建socket
    int s_sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (-1 == s_sockfd)
    {
        perror("socket failed");
        return -1;
    }

    // 2.绑定地址
    SockAddrIn serverAddr;
    // ipv4协议
    serverAddr.sin_family = AF_INET;
    // 端口
    serverAddr.sin_port = htons(8888);
    // ip地址
    serverAddr.sin_addr.s_addr = inet_addr("192.168.118.129");

    // 创建一个用于存放的json字符的数组
    char *jsonString;

    // 3.连接服务器
    int ret = connect(s_sockfd, (SockAddr *)&serverAddr, sizeof(serverAddr));
    if (-1 == ret)
    {
        perror("connect failed");
        return -1;
    }

    // 4.1 接收服务器消息
    char buf[2048] = {0};
    ret = recv(s_sockfd, buf, sizeof(buf), 0);
    if (-1 == ret)
    {
        perror("recv failed");
        return -1;
    }

    int uid, fid;
    uid = atoi(argv[1]);
    fid = atoi(argv[2]);
    printf("uid = %d\n", uid);
    printf("fid = %d\n", fid);
    printf("s_sockfd = %d\n", s_sockfd);

    // 判断上一个进程传来的数据
    if (strcmp(argv[3], "私聊") == 0)
    {
        // 向服务端发送自己的状态
        int stat = 1;
        send(s_sockfd, &stat, sizeof(stat), 0);
        // 私聊
        // 发送uid
        send(s_sockfd, &uid, sizeof(uid), 0);
        // 发送fid
        send(s_sockfd, &fid, sizeof(fid), 0);
        //puts("待接收历史消息");

        // 清空buf
        memset(buf, 0, sizeof(buf));
        // 接收聊天记录
        recv(s_sockfd, buf, sizeof(buf), 0);
        //puts("历史消息接收完毕:");
        puts(buf);
        puts("以上是历史消息");
        // 创建线程
        pthread_create(&tid1, NULL, s_private_chat, &s_sockfd);
        pthread_create(&tid2, NULL, r_private_chat, &s_sockfd);
        // 等待线程结束
        pthread_join(tid1, NULL);
    }
    else if (strcmp(argv[3], "群聊") == 0)
    {
        // 向服务端发送自己的状态
        int stat = 2;
        send(s_sockfd, &stat, sizeof(stat), 0);
        // 公屏聊天
        // 发送uid
        send(s_sockfd, &uid, sizeof(uid), 0);
        
        puts("开始聊天");

        // 创建线程
        pthread_create(&tid1, NULL, s_private_chat, &s_sockfd);
        pthread_create(&tid2, NULL, r_private_chat, &s_sockfd);
        // 等待线程结束
        pthread_join(tid1, NULL);
    }

    // 5.关闭socket
    close(s_sockfd);
    puts("关闭socket");
    return 0;
}

makefile

SRCS = $(wildcard *.c)
OBJS = $(patsubst *.c,*.o,$(SRCS))
CC = gcc
TARGET = p_chat
LDFLAGS = -lpthread -lmysqlclient

.PHONY : clean

$(TARGET) : $(OBJS)
	$(CC)  $^ -o $@ $(LDFLAGS)
	
clean :
	rm *.o

run :
	./$(TARGET)

show :
	echo $(SRCS) / $(OBJS)

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

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

相关文章

联想 SR590 服务器 530-8i RAID 控制器更换损坏的硬盘

坏了的硬盘会自动亮黄灯。用一个空的新盘来替换&#xff0c;新盘最好不要有东西。但是有东西可能也没啥&#xff0c;因为我看 RAID 控制器里有格式化的选项 1. 从 IPMI 把服务器关机&#xff0c;电源键进入绿色闪烁状态 2. 断电&#xff0c;推开塑料滑块拉出支架&#xff0c;…

城电科技|会追日的智能花,光伏太阳花开启绿色能源新篇章

当艺术与科技相遇&#xff0c;会碰撞出怎样的火花&#xff1f;城电科技推出的光伏太阳花&#xff0c;以其独特的设计与智能化的功能&#xff0c;给出了答案。这款产品不仅具备太阳能发电的实用功能&#xff0c;更是一件充满科技属性的艺术性光伏产品&#xff0c;吸引了广泛关注…

基于YOLO11深度学习的苹果叶片病害检测识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

多智能体框架

多个不同的角色的Agent&#xff0c;共同完成一份复杂的工作。由一个统筹管理的智能体&#xff0c;自主规划多个智能体分别做什么&#xff0c;以及执行的顺序。 agent 应该包含的属性 执行特定任务 根据其角色和目标做出决策 能够使用工具来实现目标 与其他代理沟通和协作 保留…

C#中级教程(1)——解锁 C# 编程的调试与错误处理秘籍

一、认识错误&#xff1a;编程路上的 “绊脚石” 在 C# 编程中&#xff0c;错误大致可分为两类&#xff1a;语法错误和语义错误&#xff08;逻辑错误&#xff09;。语法错误就像是写作文时的错别字和病句&#xff0c;编译器一眼就能识别出来&#xff0c;比如变量名拼写错误、符…

Jmeter接口并发测试

Apache JMeter 是一款开源的性能测试工具&#xff0c;广泛用于接口并发测试、负载测试和压力测试。以下是使用 JMeter 进行接口并发测试的详细步骤&#xff1a; 一、准备工作 安装 JMeter 下载地址&#xff1a;Apache JMeter 官网 确保已安装 Java 环境&#xff08;JMeter 依…

MySQL-增删改查

一、Create(创建) &#x1f4d6; 语法&#xff1a; INSERT INTO table_name(value_list); 当我们使用表的时候&#xff0c;就可以使用这个语法来向表中插入元素~ 我们这边创建一个用于示范的表(Student)~ create table student( id int, name varchar(20), chinese int, math…

开源堡垒机 JumpServer 社区版实战教程:发布机的配置与Website资产配置使用

文章目录 开源堡垒机 JumpServer 社区版实战教程&#xff1a;发布机的配置与Website资产配置使用一、功能简述二、应用发布机2.1 版本要求2.2 创建应用发布机2.2.1 通过WinRM的协议进行应用发布机的创建2.2.2 通过OpenSSH的协议进行应用发布机的创建2.2.2.1 下载OpenSSH2.2.2.2…

代码随想录算法训练day64---图论系列8《拓扑排序dijkstra(朴素版)》

代码随想录算法训练 —day64 文章目录 代码随想录算法训练前言一、53. 117. 软件构建—拓扑排序二、47. 参加科学大会---dijkstra&#xff08;朴素版&#xff09;总结 前言 今天是算法营的第64天&#xff0c;希望自己能够坚持下来&#xff01; 今天继续图论part&#xff01;今…

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷(四)

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;四&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务 1&#xff1a;应急响应&…

单片机的串口(USART)

Tx - 数据的发送引脚&#xff0c;Rx - 数据的接受引脚。 串口的数据帧格式 空闲状态高电平&#xff0c;起始位低电平&#xff0c;数据位有8位校验位&#xff0c;9位校验位&#xff0c;停止位是高电平保持一位或者半位&#xff0c;又或者两位的状态。 8位无校验位传输一个字节…

动态规划(背包问题)--是否逆序使用的问题--二进制拆分的问题

动态规划&#xff08;背包问题&#xff09; 题目链接01背包代码 完全背包问题代码 多重背包问题 I代码 什么时候适用逆序多重背包问题 II&#xff08;超百万级的复杂度&#xff09;代码 关于二进制拆分 题目链接 01背包 代码 #include <iostream> #include <vector&…

Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)

安装&#xff1a; 1、首先按照此视频的流程一步一步进行安装&#xff1a;(macos版&#xff09;ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南&#xff1a;https://ragflow.io 3、RAGflow 下载地址&#xff1a;https://github.com/infi…

姿态矩阵/旋转矩阵/反对称阵

物理意义&#xff0c;端点矢量角速率叉乘本身向量&#xff1b; 负号是动系b看固定系i是相反的&#xff1b; 一个固定 在惯性导航解算中&#xff0c;旋转矢量的叉乘用于描述姿态矩阵的微分方程。你提到的公式中&#xff0c; ω i b b \boldsymbol{\omega}_{ib}^b \times ωibb…

【大语言模型】【整合版】DeepSeek 模型提示词学习笔记(散装的可以看我之前的学习笔记,这里只是归纳与总结了一下思路,内容和之前发的差不多)

以下是个人笔记的正文内容: 原文在FlowUs知识库上&#xff0c;如下截图。里面内容和这里一样&#xff0c;知识排版好看一点 一、什么是 DeepSeek 1. DeepSeek 简介 DeepSeek 是一家专注于通用人工智能&#xff08;AGI&#xff09;的中国科技公司&#xff0c;主攻大模型研发与…

ollama无法通过IP:11434访问

目录 1.介绍 2.直接在ollama的当前命令窗口中修改&#xff08;法1&#xff09; 3.更改ollama配置文件&#xff08;法2&#xff09; 3.1更新配置 3.2重启服务 1.介绍 ollama下载后默认情况下都是直接在本地的11434端口中运行&#xff0c;绑定到127.0.0.1(localhost)&#x…

Bugku CTF CRYPTO

Bugku CTF CRYPTO 文章目录 Bugku CTF CRYPTO聪明的小羊ok[-<>]散乱的密文.!? 聪明的小羊 描 述: 一只小羊翻过了2个栅栏 fa{fe13f590lg6d46d0d0} 分 析&#xff1a;栅栏密码&#xff0c;分2栏&#xff0c;一个栏里有11个 ①手动解密 f a { f e 1 3 f 5 9 0 l g 6 d 4 …

【洛谷】【ARC100E】Or Plus Max(高维前缀和)

传送门&#xff1a;Or Plus Max 高维前缀和 题目描述 長さ 2N の整数列 A0​, A1​, ..., A2N−1​ があります。&#xff08;添字が 0 から始まることに注意&#xff09; 1 ≤ K ≤ 2N−1 を満たすすべての整数 K について、次の問題を解いてください。 i,j を整数と…

SmolLM2:多阶段训练策略优化和高质量数据集,小型语言模型同样可以实现卓越的性能表现

SmolLM2 采用创新的四阶段训练策略&#xff0c;在仅使用 1.7B 参数的情况下&#xff0c;成功挑战了大型语言模型的性能边界&#xff1a; 在 MMLU-Pro 等测试中超越 Qwen2.5-1.5B 近 6 个百分点数学推理能力&#xff08;GSM8K、MATH&#xff09;优于 Llama3.2-1B在代码生成和文…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…