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

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[])
{// 创建线程idpthread_t tid1;pthread_t tid2;// 1.创建socketint 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);// 私聊// 发送uidsend(s_sockfd, &uid, sizeof(uid), 0);// 发送fidsend(s_sockfd, &fid, sizeof(fid), 0);//puts("待接收历史消息");// 清空bufmemset(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);// 公屏聊天// 发送uidsend(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.关闭socketclose(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 *.orun :./$(TARGET)show :echo $(SRCS) / $(OBJS)

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

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

相关文章

CentOS环境变量配置+解析

环境变量的作用就是让系统快速通过你的命令找到你的可执行程序&#xff0c;windows系统里也同理&#xff0c;也就是你每次输入个命令&#xff0c;系统就会找环境变量里到底有没有叫这个命令进程的 一、环境变量配置 1.编辑配置文件 vim /etc/profile export PATH$PATH:$JAVA…

einops测试

文章目录 1. einops2. code3. pytorch 1. einops einops 主要是通过爱因斯坦标记法来处理张量矩阵的库&#xff0c;让矩阵处理上非常简单。 conda : conda install conda-forge::einopspython: 2. code import torch import torch.nn as nn import torch.nn.functional as…

Unity教程(二十一)技能系统 基础部分

Unity开发2D类银河恶魔城游戏学习笔记 Unity教程&#xff08;零&#xff09;Unity和VS的使用相关内容 Unity教程&#xff08;一&#xff09;开始学习状态机 Unity教程&#xff08;二&#xff09;角色移动的实现 Unity教程&#xff08;三&#xff09;角色跳跃的实现 Unity教程&…

Docker:Docker从入门到精通(一)- Docker简介

一、前言 通过本专栏的学习&#xff0c;我们将了解   1. 掌握Docker基础知识&#xff0c;能够理解Docker镜像与容器的概念   2. 完成Docker安装与启动   3. 掌握Docker镜像与容器相关命令   4. 掌握Tomcat Nginx 等软件的常用应用的安装   5. 掌握docker迁移与备份相…

单机上使用docker搭建minio集群

单机上使用docker搭建minio集群 1.集群安装1.1前提条件1.2步骤指南1.2.1安装 Docker 和 Docker Compose&#xff08;如果尚未安装&#xff09;1.2.2编写docker-compose文件1.2.3启动1.2.4访问 2.使用2.1 mc客户端安装2.2创建一个连接2.3简单使用下 这里在ubuntu上单机安装一个m…

Image Downloader下载文章图片的WordPress插件

源码介绍 一个用于下载图片的WordPress插件&#xff0c;包含下载统计功能&#xff0c;支持任何主题使用 用户点击下载后自动打包该文章所有原始图片&#xff0c;并把文章标题作为压缩包的文件名。 不占用服务器空间&#xff0c;也不占网盘空间&#xff0c;直接利用浏览器的性…

PLC通讯

PPI通讯 是西门子公司专为s7-200系列plc开发的通讯协议。内置于s7-200 CPU中。PPI协议物理上基于RS-485口&#xff0c;通过屏蔽双绞线就可以实现PPI通讯。PPI协议是一种主-从协议。主站设备发送要求到从站设备&#xff0c;从站设备响应&#xff0c;从站不能主动发出信息。主站…

VScode+stfp插件,实现文件远程同步保存【2025实操有效】

目录 1 痛点2 准备工作3 操作步骤3.1 第一步&#xff0c;下载STFP插件3.2 第二步&#xff0c;修改配置文件3.3 第三步&#xff0c;测试是否成功 4 后记 1 痛点 我一直用vscode远程连接服务器&#xff0c;传代码文件等到服务器上面&#xff0c;突然有一次服务器那边尽心维修&am…

【quicker】调节PPT指定字号字体大小/快速调节WPS的PPT字体大小

在quicker的拓展动作中找不到直接指定字号大小方式的动作。 换个思路&#xff0c;既然无法通过alt键模拟&#xff0c;不如模拟右键菜单触发&#xff1f;尝试过失败了 所以有了第三种方法 &#xff0c;首先给字体窗口设置快捷键&#xff0c;此处设置的是altshiftf&#xff0c;然…

Grouped-Query Attention(GQA)详解: Pytorch实现

Grouped-Query Attention&#xff08;GQA&#xff09;详解 Grouped-Query Attention&#xff08;GQA&#xff09; 是 Multi-Query Attention&#xff08;MQA&#xff09; 的改进版&#xff0c;它通过在 多个查询头&#xff08;Query Heads&#xff09;之间共享 Key 和 Value&am…

百度百舸 DeepSeek 一体机发布,支持昆仑芯 P800 单机 8 卡满血版开箱即用

在私有云环境中成功部署 DeepSeek 满血版并实现性能调优&#xff0c;并不是一件容易的事情。选择合适的 GPU 配置、安装相应的环境、成功部署上线业务、加速推理任务加速、支撑多用户并发 …… 完成业务测试&#xff0c;成功融入生产业务中。 为了帮助企业快速实现 DeepSeek 服…

c++入门-------命名空间、缺省参数、函数重载

C系列 文章目录 C系列前言一、命名空间二、缺省参数2.1、缺省参数概念2.2、 缺省参数分类2.2.1、全缺省参数2.2.2、半缺省参数 2.3、缺省参数的特点 三、函数重载3.1、函数重载概念3.2、构成函数重载的条件3.2.1、参数类型不同3.2.2、参数个数不同3.2.3、参数类型顺序不同 前言…

tortoiseGit的使用和上传拉取

tortoiseGit的使用和上传拉取 下载TortoiseGit 通过网盘分享的文件&#xff1a;tortoiseGit.zip 链接: https://pan.baidu.com/s/1EOT_UsM9_OysRqXa8gES4A?pwd1234 提取码: 1234 在电脑桌面新建文件夹并进入 右击鼠标 将网址复制上去 用户名和密码是在git注册的用户名和…

Mybatis学习总结

官网 概念 用于简化JDBC的开发。 在配置mybatis的时候如果没有建立连接识别不了信息&#xff0c;我们需要在idea配置mysql的配置信息 JDBC是一套操作关系数据库的API&#xff0c;有效率&#xff0c;和mybatis比起来资源节约&#xff0c;性能高&#xff0c;不繁琐。 数据库连…

SQL笔记#数据更新

一、数据的插入(INSERT语句的使用方法) 1、什么是INSERT 首先通过CREATE TABLE语句创建表&#xff0c;但创建的表中没有数据&#xff1b;再通过INSERT语句向表中插入数据。 --创建表ProductIns CREATE TABLE ProductIns (product_id CHAR(4) NOT NULL,product_name …

dockerfile构建haproxy

1. 结构目录 [rootlocalhost ~]# tree haproxy/ haproxy/ ├── dockerfile └── files├── haproxy-2.5.0.tar.gz├── haproxy.cfg├── install.sh└── start.sh1 directory, 5 files [rootlocalhost ~]# [rootlocalhost ~]# cd haproxy/ [rootlocalhost haproxy]…

Docker(Nginx)部署Vue

简介&#xff1a;目标使用docker将vue生成的dist文件&#xff0c;结合nginx生成镜像&#xff0c;然后运行&#xff1b; 1、首选确保vue项目正确运行&#xff0c;并能正确打包dist文件&#xff1b; 2、查看已经生成的dist文件 3、将dist文件打包为rar文件或者zip文件&#xf…

C++——模版(二)

前言 我们前面讲过模版的一&#xff0c;不知道大家还有没有所印象&#xff0c;如果大家不太能回忆起来可以再去前面看一下&#xff0c;那通过我们讲解了几个容器之后&#xff0c;相信大家现在应该已经对模版很熟悉了&#xff0c;那模版还剩下一些其他的内容我们就在这里进行讲…

算法与数据结构(旋转链表)

题目 思路 每个节点向右移动k个位置&#xff0c;其实就是从头开始遍历&#xff0c;将n-k个节点顺序插入到链表的尾部。 如上图所示的示例1&#xff0c;先将1插入到5的后面&#xff0c;再将2插入到1的后面&#xff0c;最后将3插入到2的后面即可。 代码详解 定义一个cur变量用…

TOGAF之架构标准规范-信息系统架构 | 应用架构

TOGAF是工业级的企业架构标准规范&#xff0c;信息系统架构阶段是由数据架构阶段以及应用架构阶段构成&#xff0c;本文主要描述信息系统架构阶段中的应用架构阶段。 如上所示&#xff0c;信息系统架构&#xff08;Information Systems Architectures&#xff09;在TOGAF标准规…