广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言实现四窗口聊天
  • 253
分享到

C语言实现四窗口聊天

2024-04-02 19:04:59 253人浏览 薄情痞子
摘要

C语言实现四窗口聊天,供大家参考,具体内容如下 为了练习前段时间学习的共享内存、管道、消息队列等进程同步机制,做了一个聊天小项目。 项目描述: 有4个进程,A进程和B进程负责通信,从

C语言实现四窗口聊天,供大家参考,具体内容如下

为了练习前段时间学习的共享内存、管道、消息队列等进程同步机制,做了一个聊天小项目

项目描述:

有4个进程,A进程和B进程负责通信,从标准输入读到的字符串通过管道发给对方,A1和B1进程负责显示,其中:

  • A进程和B进程通过管道通信,A进程和A1进程通过共享内存通信,B进程和B1进程通过消息队列通信;
  • A进程从标准输入读到的字符串后,放到管道和共享内存里,从管道中读到的字符串放到共享内存里,B进程从管道中拿到A放的字符串,A1进程到共享内存中拿到字符串,打印到屏幕上;
  • B进程从标准输入读到的字符串发给A进程,同时通过消息队列发给B1进程,B1进程从消息队列中读出消息,打印到屏幕上;
  • 退出时,在A和B任意一个进程中输入 Crtl+c 或者 Ctrl+\ ,四个进程会删除所有管道、共享内存、消息队列等资源,然后有序退出。

操作系统ubuntu20.4

语言:c

编译器:GCc

func.h


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <time.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <signal.h>

#define ARGS_CHECK(argc, num){if(argc!=num){fprintf(stderr,"args error!\n"); return -1;}}

#define ERROR_CHECK(ret,num,msg){if(ret == num){perror(msg); return -1;}}

a.c


//========= A窗口 ===========
//1.从标准输入读取数据,通过有名管道发送给B窗口
//2.接收从B窗口发送过来的数据
//3.通过共享内存和信号量,将从B来的数据发送给A1
//===========================

#include <func.h>

int chatA(int shmid, int semid, char *p);
int sndToA1(int semid, int shmid, char *p, char *msg);//把要打印的消息发送给A1
void closeAll();//把关闭消息发送出去,关闭共享内存和信号量集
void sigFunc(int signum);//新的2号和3号信号处理函数,如果在A窗口发生2号和3号信号就调用close函数

//全局变量,后面捕获到退出信号回收资源时使用
int semid;
int shmid;//共享内存
char *p;

int fdWrite;
int fdRead;

int main()
{
    //1.创建信号量集,如果有新消息就往共享内存中写,类似生产者
    semid = semget(2000, 1, IPC_CREAT|0666);
    ERROR_CHECK(semid, -1, "A semget");
    shmid = shmget(1000, 4096, IPC_CREAT|0666);//创建一个共享内存
    ERROR_CHECK(shmid, -1, "shmget");
    p = (char *)shmat(shmid, NULL, 0);

    signal(SIGINT, sigFunc);
    signal(SIGQUIT, sigFunc);

    int ret = chatA(shmid, semid, p);
    ERROR_CHECK(ret, -1, "run A");//检查是否成功打开通信窗口
    return 0;
}

int chatA(int shmid, int semid, char *p){
    //成功运行返回1,否则返回-1
    fdRead = open("1.pipe", O_RDONLY);//以只读模式打开管道1
    ERROR_CHECK(fdRead, -1, "open fdRead");//检查是否成功打开
    fdWrite = open("2.pipe", O_WRONLY);//以只写模式打开管道2
    ERROR_CHECK(fdWrite, -1, "open fdWrite");//检查
    setbuf(stdin, NULL);
    puts("=========== A ===========");
    char buf[512] = {0};
    fd_set rdset;//设置一个信箱,用来监控有没有读取到信息
    while(1){
        struct timeval timeout;//设置超时
        timeout.tv_sec = 5;
        timeout.tv_usec = 15000000;//超过5秒没有接收到信息就是超时
        FD_ZERO(&rdset);//初始化集合,清空信箱
        FD_SET(fdRead, &rdset);//将要监听的管道1注册到集合中
        FD_SET(STDIN_FILENO, &rdset);//将要监听的标准输入注册到集合中
        int tret = select(fdRead + 1,&rdset,NULL,NULL,&timeout);//调用select进行监听
        if(tret == 0){
            puts("time out!");
        }
        //select阻塞进程,任意一个FD就绪,解除阻塞
        //解除阻塞,检查是谁就绪
        if(FD_ISSET(fdRead, &rdset)){
            //如果是管道就绪,读取管道中的内容,发送给A1
            memset(buf, 0, sizeof(buf));//清空buf中的内容,用来接收管道中的信息
            int ret = read(fdRead, buf, 1024);//将管道中的信息读取出来
            if(ret == 0){
                //如果另一端对管道的写先关闭了,退出聊天
                sigFunc(2);
                break;
            }
            //获取从B来的消息的类型
            int type = 0;
            sscanf(buf, "%*d %d", &type);//读取消息的类别,1类为正常,2类为关闭所有窗口
            int snd_ret = 0;
            
            switch (type){
            case 1:
                //如果是1号信息,通过共享内存直接把消息发送给A1
                snd_ret = sndToA1(shmid, semid, p, buf);
                ERROR_CHECK(snd_ret, -1, "sndToA1");
                break;
            case 2:
                //=====如果是从B发过来的2号信息,关闭所有窗口=====
                //向A1发送一个空的2号信号,让A1自己退出,然后自己再退出
                sigFunc(2);
                exit(0);
            }
        }
        if(FD_ISSET(STDIN_FILENO, &rdset)){
            //如果标准输入准备就绪,读取标准输入区的数据,标记为3号信号,发送给A1和B
            time_t localtm;
            time(&localtm);//获取当前时间
            localtm += 8*3600;
            memset(buf, 0, sizeof(buf));//清空buf
            int ret = read(STDIN_FILENO, buf, 1024);//读取数据
            if(ret == 0){
                //如果在标准输入中读到了终止符,退出聊天窗口
                puts("I quite.");
                break;
            }
            char sstoA1[1024] = {0};//用来拼接数据,发送给A1的数据
            char sstoB[1024] = {0};//用来拼接数据,发送给B的数据
            sprintf(sstoA1, "%ld %d %s", localtm, 3, buf); //标注为三号信号发送给A1
            sprintf(sstoB, "%ld %d %s", localtm, 1, buf); //标注为1号信号发送给B
            sndToA1(shmid, semid, p, sstoA1);//发送给A1
            write(fdWrite, sstoB, sizeof(sstoB));//通过管道发送给B
        }
    }
    close(fdRead);
    close(fdWrite);
    return 1;//程序成功运行结束,返回1
}

int sndToA1(int shmid, int semid, char *p, char *msg){
    //使用共享内存和信号量给A1传递信息
    //信号量集的操作,如果有新消息就往共享内存中写,类似生产者
    struct sembuf V;
    V.sem_num = 0;
    V.sem_op = +1;
    V.sem_flg = SEM_UNDO;
    semop(semid, &V, 1);
    
    ERROR_CHECK(shmid, -1, "shmget");
    
    memcpy(p, msg, strlen(msg));//向共享内存中写信息
    return 1;
}

void closeAll(){
    //根据共享内存和信号量级的标识符,关闭并删除它们
    write(fdWrite, "0 2 0", 5);//通过管道发送给B
    shmdt(p);
    shmctl(shmid, IPC_RMID, NULL);
    semctl(semid, IPC_RMID, 0);
    close(fdWrite);
    close(fdRead);
    exit(0);
}

void sigFunc(int signum){
    printf("Bye Bye.\n");
    //捕捉2号和3号信号,发送关闭信息给A1,然后调用closeAll
    sndToA1(shmid, semid, p, "0 2 0");//发送给A1
    usleep(500);
    closeAll();
}

b.c


//========= B窗口 ===========
//1.从标准输入读取数据,通过有名管道发送给A窗口
//2.接收从A窗口发送过来的数据
//3.通过共享内存和信号量,将从A来的数据发送给B1
//===========================

#include <func.h>

//自定义一个消息结构体,用来和B1传递数据
typedef struct myMsg{
    long mtype;
    char mtext[512];
}myMsg_t;

int chatB(char *pipe1, char *pipe2);
int sndToB1(int msqid, char *msg);//把从A来的消息发送给B1
void closeAll();
void sigFunc(int signum);

//全局变量,后面回收资源时要用到
int msqid;
int fdWrite;
int fdRead;

int main()
{
    msqid = msgget(3000, IPC_CREAT|0666);
    ERROR_CHECK(msqid, -1, "B msgget");

    //注册新的信号处理函数
    signal(SIGINT, sigFunc);
    signal(SIGQUIT, sigFunc);

    int ret = chatB("./1.pipe", "./2.pipe");
    ERROR_CHECK(ret, -1, "run B");
    return 0;
}

int chatB(char *pipe1, char *pipe2){
    //通信窗口2,读管道2中的信息,向管道1写信息
    fdWrite = open(pipe1, O_WRONLY);
    ERROR_CHECK(fdWrite, -1, "open pipe1");
    fdRead = open(pipe2, O_RDONLY);
    ERROR_CHECK(fdRead, -1, "open pipe2");
    setbuf(stdin, NULL);
    puts("============ B ============");
    char buf[512] = {0};
    fd_set rdset;//设置集合,用来监听
    while(1){
        //利用集合设置阻塞
        struct timeval timeout;
        timeout.tv_sec = 5;
        timeout.tv_usec = 15000000;
        FD_ZERO(&rdset);//初始化集合
        FD_SET(fdRead, &rdset);
        FD_SET(STDIN_FILENO, &rdset);
        int tret = select(fdRead+1,&rdset,NULL,NULL,&timeout);
        if(tret == 0){
            puts("time out!");
        }

        //集合中有就绪的,检查是谁就绪,并进行相应的操作
        if(FD_ISSET(fdRead, &rdset)){
            //如果是管道就绪,读取数据并发送给B1
            memset(buf, 0, sizeof(buf));
            int ret = read(fdRead, buf, 1024);
            if(ret == 0){
                sigFunc(2);
                break;
            }
            int type = 0;//用来存储消息的类型
            sscanf(buf, "%*d %d", &type);//从消息中获取类型信息

            //如果是2号信息,关闭所有窗口
            //向B1发送关闭信号,然后回收消息队列,再自己结束
            if(type == 2){
                sigFunc(2);
                exit(0);
            }

            //如果是其他有效信息,发送给B1
            int snd_ret = sndToB1(msqid, buf);
            ERROR_CHECK(snd_ret, -1, "B sndToB1");
        }
        if(FD_ISSET(STDIN_FILENO, &rdset)){
            //如果是标准输入区就绪,读取数据,分别发给A和B1
            time_t localtm;
            time(&localtm);//获取当前时间
            localtm += 8*3600;
            memset(buf, 0, sizeof(buf));
            int ret = read(STDIN_FILENO, buf, 1024);
            if(ret == 0){
                puts("I quite.");
                break;
            }
            //按照协议拼接数据并发送出去
            char sstoA[1024] = {0};//发送给A的数据
            sprintf(sstoA, "%ld %d %s", localtm, 1, buf); 
            write(fdWrite, sstoA, sizeof(sstoA));

            char sstoB1[1024] = {0};//发送给B1的数据标注为3号
            sprintf(sstoB1, "%ld %d %s", localtm, 3, buf); 
            sndToB1(msqid, sstoB1);
        }
    }
    close(fdRead);
    close(fdWrite);
    return 1;//程序成功运行结束,返回1
}

int sndToB1(int msqid, char *msg){
    //通过消息队列,把数据发送给B1
    myMsg_t msgtoB1;//创建一个消息结构体
    msgtoB1.mtype = 1;
    memset(msgtoB1.mtext, 0, sizeof(msgtoB1.mtext));
    memcpy(msgtoB1.mtext, msg, strlen(msg));
    msgsnd(msqid, &msgtoB1, strlen(msg), 0);
    return 1;
}

void closeAll(){
    msgctl(msqid, IPC_RMID, 0);//删除消息队列
    close(fdWrite);//关闭管道
    close(fdRead);
    exit(0);
}

void sigFunc(int signum){
    printf("Bye Bye.\n");
    //通过消息队列,把关闭信息发送给B1,然后删除消息队列,然后自己退出
    sndToB1(msqid, "0 2 0");//发送给B1关闭信号
    write(fdWrite, "0 2 0", 5);//发送给A关闭信号
    usleep(500);//睡一下,等B1先关闭
    //捕获2号和3号信号,调用closeAll函数
    closeAll();
}

a1.c


//========== A1 ==========
//1.从共享内存中读取消息
//2.打印

int display();

#include <func.h>

int main()
{
    int ret = display();
    ERROR_CHECK(ret, -1, "A1 display");
    return 0;
}

int display(){
    //1.从共享内存中读取数据
    //没有消息就等待,有消息就读取,使用信号量集,类似消费者
    //1.1 创建一个信号量集,如果共享内存中有数据就读取,如果共享内存中没有数据就阻塞
    int semid = semget(2000, 1, IPC_CREAT|0666);
    ERROR_CHECK(semid, -1, "A1 semget");
    semctl(semid, 0, SETVAL, 0);//信号量初始值设为0
    //设置信号量,测试并取资源,类似消费者操作
    struct sembuf P;
    P.sem_num = 0;
    P.sem_op = -1;
    P.sem_flg = SEM_UNDO;
    printf("=========== A1 ===========\n");
    while(1){
        semop(semid, &P, 1);//P操作,测试并取资源
        int shmid = shmget(1000, 4096, IPC_CREAT|0666);
        ERROR_CHECK(shmid, -1, "A1 shmget");
        char *p = (char *)shmat(shmid, NULL, 0);//连接共享内存

        int type = 0;
        sscanf(p, "%*d %d", &type);//获取消息的属性,然后根据协议执行相应的操作
        switch (type){
        case 1:
            //从B来的消息
            printf("<<<<<<<<< receive <<<<<<<<<<\n");
            struct tm *ptm = NULL;
            time_t tmp = 0;
            char ss[512] = {0};
            sscanf(p, "%ld", &tmp);//读取消息中的时间信息
            sscanf(p, "%*d %*d %[^\n]", ss);
            ptm = gmtime(&tmp);
            printf("%4d-%02d-%02d %02d:%02d:%02d\n",
                   ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,
                   ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
            puts(ss);
            printf("\n");
            //清空共享内存中的数据
            memset(p, 0, 4096);
            break;
        case 2:
            printf("Bye Bye.\n");
            shmdt(p);
            shmctl(shmid, IPC_RMID, NULL);
            exit(0);
            break;
        case 3:
            printf(">>>>>>>>>  send  >>>>>>>>>>>\n");
            struct tm *ptm3 = NULL;
            time_t tmp3 = 0;
            char ss3[512] = {0};
            sscanf(p, "%ld", &tmp3);//读取消息中的时间信息
            sscanf(p, "%*d %*d %[^\n]", ss3);
            ptm3 = gmtime(&tmp3);
            printf("%4d-%02d-%02d %02d:%02d:%02d\n",
                   ptm3->tm_year+1900,ptm3->tm_mon+1,ptm3->tm_mday,
                   ptm3->tm_hour, ptm3->tm_min, ptm3->tm_sec);
            puts(ss3);
            printf("\n");
            //清空共享内存中的数据
            memset(p, 0, 4096);
            break;
        default:
            printf("sonething wrong!\n");
        }
    }
}

b1.c


//========== B1 ===========
//接收来自B的消息,并打印

#include <func.h>

typedef struct myMsg{
    long mtype;
    char mtext[512];
}myMsg_t;

int display();

int main()
{
    int ret = display();
    ERROR_CHECK(ret, -1, "B1 display");
    return 0;
}

int display(){
    printf("=========== B1 ===========\n");
    while(1){
        //接收来自B的消息
        int msqid = msgget(3000, IPC_CREAT|0666);
        ERROR_CHECK(msqid, -1, "B1 msgget");
        myMsg_t msgfromB;
        memset(&msgfromB, 0, sizeof(msgfromB));
        msgrcv(msqid, &msgfromB, sizeof(msgfromB.mtext), 1, 0);
        //1.如果是2类信号,退出
        int type = 0;
        sscanf(msgfromB.mtext, "%*d %d", &type);//读取消息的属性,根据不同属性,执行相应的操作

        switch (type){
        case 1:
            //从B来的消息
            printf("<<<<<<<<< receive <<<<<<<<<<\n");
            struct tm *ptm = NULL;
            time_t tmp = 0;
            char ss[512] = {0};
            sscanf(msgfromB.mtext, "%ld", &tmp);//读取消息中的时间信息
            sscanf(msgfromB.mtext, "%*d %*d %[^\n]", ss);
            ptm = gmtime(&tmp);
            printf("%4d-%02d-%02d %02d:%02d:%02d\n",
                   ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday,
                   ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
            puts(ss);
            printf("\n");
            //清空共享内存中的数据
            break;
        case 2:
            //删除消息队列并退出
            printf("Bye Bye.\n");
            msgctl(msqid, IPC_RMID, NULL);
            exit(0);
        case 3:
            printf(">>>>>>>>>  send  >>>>>>>>>>>\n");
            struct tm *ptm3 = NULL;
            time_t tmp3 = 0;
            char ss3[512] = {0};
            sscanf(msgfromB.mtext, "%ld", &tmp3);//读取消息中的时间信息
            sscanf(msgfromB.mtext, "%*d %*d %[^\n]", ss3);
            ptm3 = gmtime(&tmp3);
            printf("%4d-%02d-%02d %02d:%02d:%02d\n",
                   ptm3->tm_year+1900,ptm3->tm_mon+1,ptm3->tm_mday,
                   ptm3->tm_hour, ptm3->tm_min, ptm3->tm_sec);
            puts(ss3);
            printf("\n");
            break;
        default:
            printf("Something wrong!\n");
        }
    }
}

运行如下:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: C语言实现四窗口聊天

本文链接: https://www.lsjlt.com/news/128167.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C语言实现四窗口聊天
    C语言实现四窗口聊天,供大家参考,具体内容如下 为了练习前段时间学习的共享内存、管道、消息队列等进程同步机制,做了一个聊天小项目。 项目描述: 有4个进程,A进程和B进程负责通信,从...
    99+
    2022-11-12
  • C#实现QQ聊天窗口
    本文实例为大家分享了C#实现QQ聊天窗口的具体代码,供大家参考,具体内容如下 分析 需要两个TextBox,一个用于显示消息,一个用于编辑消息需要四个按钮,分别控制关闭程序,清空正在...
    99+
    2022-11-13
  • C#实现简化QQ聊天窗口
    本文实例为大家分享了C#实现简化QQ聊天窗口的具体代码,供大家参考,具体内容如下 如图样式,详细步骤如下 整个窗体设置 private void Form1_Load(object...
    99+
    2022-11-13
  • 怎么用C#实现一个QQ聊天窗口
    这期内容当中小编将会给大家带来有关怎么用C#实现一个QQ聊天窗口,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。using System;using System.Collections...
    99+
    2023-06-20
  • 怎么用C#脚本实现QQ聊天窗口
    本篇内容介绍了“怎么用C#脚本实现QQ聊天窗口”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!分析需要两个TextBox,一个用于显示消息,一...
    99+
    2023-06-29
  • 怎么用C#代码实现简化QQ聊天窗口
    本文小编为大家详细介绍“怎么用C#代码实现简化QQ聊天窗口”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用C#代码实现简化QQ聊天窗口”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。如图样式,详细步骤如下整个...
    99+
    2023-06-29
  • C#实现简单的聊天窗体
    本文实例为大家分享了C#实现简单的聊天窗体的具体代码,供大家参考,具体内容如下 一、要使用(学习)到的知识点 1、textBox控件 (1)功能:允许用户输入文本,并提供多行编辑和密...
    99+
    2022-11-12
  • C语言实现简易网络聊天室
    本文实例为大家分享了C语言实现网络聊天室的具体代码,供大家参考,具体内容如下 业务逻辑: 1、客户端注册名字 2、告诉所有在线的客户端,XXX进入聊天室 3、新建一个线程为该客户端服...
    99+
    2022-11-12
  • C#实现聊天窗体以及抖动
    本文实例为大家分享了C#实现聊天窗体以及抖动的具体代码,供大家参考,具体内容如下 一、聊天窗体案例 1、聊天窗体的要求? (1)由两个文本框组以及两个按钮组成(一个只读框,一个输入框...
    99+
    2022-11-12
  • C语言实现简单的聊天室功能
    用C语言实现简单的聊天室功能,供大家参考,具体内容如下 服务器端 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> ...
    99+
    2022-11-12
  • C#中怎么实现一个聊天窗体
    这期内容当中小编将会给大家带来有关C#中怎么实现一个聊天窗体,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、textBox控件(1)功能:允许用户输入文本,并提供多行编辑和密码字符掩码功能(2)它右什么...
    99+
    2023-06-20
  • 使用QGraphicsView实现气泡聊天窗口+排雷功能
    经过多方调查,用Qt实现气泡聊天窗口的方式有如下几个: 使用QWebEngineView控件内嵌html+CSS使用QTextEdit内嵌html使用QGraphicsView实现使...
    99+
    2022-11-13
  • C#如何实现聊天窗体以及抖动功能
    本篇内容介绍了“C#如何实现聊天窗体以及抖动功能”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!本文实例为大家分享了C#实现聊天窗体以及抖动的...
    99+
    2023-06-20
  • c语言如何实现图形界面登录窗口
    在 C 语言中,要实现图形界面登录窗口,你可以使用第三方库或框架来帮助实现。以下是两种常用的方法:1. 使用第三方库:一种流行的 C...
    99+
    2023-08-15
    c语言
  • Go语言怎么实现聊天小工具
    本篇内容介绍了“Go语言怎么实现聊天小工具”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!代码实现server.gopackage ...
    99+
    2023-07-05
  • PHP微信开发:如何实现客服聊天窗口管理
    微信是目前全球用户规模最大的社交平台之一,随着移动互联网的普及,越来越多的企业开始意识到微信营销的重要性。在进行微信营销时,客服服务是至关重要的一环。为了更好地管理客服聊天窗口,我们可以借助PHP语言进行微信开发。一、PHP微信开发简介PH...
    99+
    2023-05-14
    PHP 微信开发 客服聊天窗口管理
  • 怎么使用QGraphicsView实现气泡聊天窗口+排雷功能
    这篇“怎么使用QGraphicsView实现气泡聊天窗口+排雷功能”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“怎么使用QG...
    99+
    2023-06-30
  • Vue怎么实现微信聊天窗口展示组件功能
    这篇文章主要介绍“Vue怎么实现微信聊天窗口展示组件功能”,在日常操作中,相信很多人在Vue怎么实现微信聊天窗口展示组件功能问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue怎么实现微信聊天窗口展示组件功能...
    99+
    2023-07-04
  • C语言实现贪吃蛇小黑窗
    本文实例为大家分享了C语言实现贪吃蛇小黑窗的具体代码,供大家参考,具体内容如下 思路: 1.利用整型二维数组保存显示数据,小蛇每移动一次清屏并便利数组做到动态效果。每次移动(清屏)的...
    99+
    2022-11-12
  • go语言如何实现即时通讯聊天室
    本文小编为大家详细介绍“go语言如何实现即时通讯聊天室”,内容详细,步骤清晰,细节处理妥当,希望这篇“go语言如何实现即时通讯聊天室”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。实现的功能:公聊,私聊,修改用户名...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作