Linux小项目-群聊系统

2023-05-16

  • 项目名称:chat_room群聊系统

  • 背景知识与主要技术:
    熟悉Linux基本指令的使用(ls,cd,make,mkdir,top,basename,pwd,cp,mv,rm,touch)
    熟悉linux开发环境,熟练使用vi/vim ,gcc/g++,gdb,make,makefile
    了解网络,熟悉tcp ip udp协议的使用
    熟练掌握C/C++,熟练使用C++STL中的容器
    熟悉套接字编程
    熟悉线程的使用
    熟悉shell脚本的简单编写

  • 使用的开源/系统库:
    1.jsoncpp:基于c++的json库实现数据的序列化与反序列化的功能。
    2.ncurses: 控制屏幕终端显示的库,项目中用于实现客户端界面。
    3.pthread:项目中使用该库提供线程支持。

  • 主要功能模块:
    1.server模块:基于udp协议完成用户与服务器之间的通信。
    2.comm模块:基于jsoncpp库对通讯数据进行序列化
    3.data_pool模块:基于vector与信号量对数据进行存储
    4.window模块:基于ncurses库实现客户端界面(输入框,输出框,标题,好友列表)
    5.lib模块:项目所需要的动态库
    6.log模块:打印项目的错误信息
    7.client模块:采用上述模块实现界面,与数据的发送与接收。
    8.plugin模块:服务起停与程序编译的控制脚本

  • 思想图解

  • 这里写图片描述

  • 主要模块代码

server端

#ifndef _SERVER_H_
#define _SERVER_H_
#include<iostream>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<map>
#include<string.h>
#include<pthread.h>
#include"data_pool.h"
#include"log.h"
#include"data.h"
using namespace std;
class server
{
public:
    server(string ip,int port);
    int sock_init();
    int recvmsg(string &out);
    int  sendmsg(const struct sockaddr_in &client,const string &in);
    int broadcast();
    void *handler(void *arg);
    void add_online_usr(const struct sockaddr_in *client);
    void del_online_usr(const struct sockaddr_in *client);
    ~server();
private:
    string _ip;
    int _port;
    int _sock;
    map<int,struct sockaddr_in> _onlineusr;
    pool data_pool;
};
#endif
#include"udp_server.h"
server::server(string ip,int port)
    :_ip(ip)
    ,_port(port)
    ,_sock(-1)
    ,data_pool(256)
{}
server::~server()
{
    if(_sock > 0)
        close(_sock);
}
int server::sock_init()
{
    _sock = socket(AF_INET,SOCK_DGRAM,0);
    if(_sock < 0)
    {
        print_log("socket error",ERROR);
        return -1;
    }
    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = inet_addr(_ip.c_str());
    if(bind(_sock,(struct sockaddr*)&local,sizeof(local)) < 0)
    {
        print_log("bind error",ERROR);
        return -1;
    }
    return 0;
}

int server::recvmsg(string &out)
{

        struct sockaddr_in client;
        char buf[1024];
        socklen_t len = sizeof(client);
        ssize_t s = recvfrom(_sock,buf,sizeof(buf)-1,0,\
                            (struct sockaddr*)&client,&len);
        if(s > 0)//recv success
        {
            buf[s] = 0;
            out = buf;
            data_pool.put_data(out);
            add_online_usr(&client);
            data _data;
            _data.val_to_unserialize(out);
            if(strcasecmp(_data.cmd.c_str(),"QUIT") == 0)
            {
                del_online_usr(&client);
            }
            return 0;
        }
        return -1;
}
int server::sendmsg(const struct sockaddr_in &client,const string &in)
{
    //const char *msg = in.c_str();
    if(sendto(_sock,in.c_str(),in.size(),0,(struct sockaddr*)&client,sizeof(client)))
    {
        return 0;
    }
   return -1;
}
int server::broadcast()
{
    string in;
    data_pool.get_data(in);
    map<int,struct sockaddr_in>::iterator iter = _onlineusr.begin();
    while(iter != _onlineusr.end())
    {

        sendmsg(iter->second,in);
        iter++;
    }
    return 0;
}
void server::add_online_usr(const struct sockaddr_in* client)
{
    _onlineusr.insert(std::pair<int,struct sockaddr_in>(client->sin_addr.s_addr,*client));
}
void server::del_online_usr(const struct sockaddr_in *client)
{
    map<int,struct sockaddr_in>::iterator iter = _onlineusr.find(client->sin_addr.s_addr);
    if(iter == _onlineusr.end())//can not find
    {
        return;
    }
    else
    {
        _onlineusr.erase(iter);
    }

}
#include"udp_server.h"
void *handler(void *arg)
{
    server *ser = (server*)arg;
    while(1)
    {
        ser->broadcast();
    }
}
int main(int argc,char *argv[])
{
    if(argc != 3)
    {
        std::cout << "Usage :" << argv[0] << "[ip]" << "[port]" << std::endl;
        return -1;
    }
    server ser(argv[1],atoi(argv[2]));
    ser.sock_init();
    pthread_t id;
    pthread_create(&id,NULL,handler,(void*)&ser);
    data _data;
    while(1)
    {
        string out;
        ser.recvmsg(out);
        std::cout << "client say#:" << out << std::endl;
    }
}

comm端

#ifndef _JSON_H_
#define _JSON_H_
#include"json/json.h"
#include<string>
int serialize(Json::Value &_v,std::string &str);
int unserialize(Json::Value &_v,std::string &str);
#endif
#include"base_json.h"
int serialize(Json::Value &_v,std::string &str)
{
    Json::StyledWriter _w;
    str = _w.write(_v);
    return 0;
}
int unserialize(Json::Value &_v,std::string &str)
{
    Json::Reader _r;
    if(_r.parse(str,_v,false))
    {
        return 0;
    }
    return -1;
}
#ifndef _DATA_H_
#define _DATA_H_
#include<iostream>
#include<string>
#include"base_json.h"
class data
{
    public:
        data();
        ~data();
        void val_to_serialize(std::string &str);
        void val_to_unserialize(std::string &str);
    public:
    std::string nick_name;
    std::string school;
    std::string msg;
    std::string cmd;
};
#endif
#include"data.h"
data::data()
{}
data::~data()
{}
void data::val_to_serialize(std::string &str)
{
    Json::Value _v;
    _v["nick_name"] = nick_name;
    _v["school"] = school;
    _v["msg"] = msg;
    _v["cmd"] = cmd;
    serialize(_v,str);
}
void data::val_to_unserialize(std::string &str)
{
    Json::Value _v;
    unserialize(_v,str);
    nick_name = _v["nick_name"].asString();
    school = _v["school"].asString();
    msg = _v["msg"].asString();
    cmd = _v["cmd"].asString();
}
/以下为测试代码
//int main()
//{
//  data d;
//  while(1)
//  {
//
//  std::cin >> d.nick_name;
//  std::cin >> d.school;
//  std::cin >> d.msg ;
//  d.cmd = "";
//  std::string str;
//  d.val_to_serialize(str);
//  std::cout << str << std::endl;
//  d.val_to_unserialize(str);
//  std::cout << d.nick_name << std::endl;
//  std::cout << d.school << std::endl;
//  std::cout << d.msg << std::endl;
//
//  }
//
//  return 0;
//}

window端—界面实现

#include<iostream>
#include<string>
#include<ncurses.h>
class window
{
    public:
    window();
    ~window();
    void create_win(WINDOW *& _win,int _h,int _w,int _y,int _x);
    void create_header();
    void create_output();
    void create_input();
    void create_friends_list();
    void put_str_to_window(WINDOW *_win,int _y,int _x,std::string str);
void get_str_window(WINDOW *_win,std::string &msg);
void fflush(WINDOW *_win);
    public:
    WINDOW * _header;
    WINDOW * _output;
    WINDOW * _input;
    WINDOW * _friends_list;
};
#include"window.h"
window::window()
{
    initscr();
}
window::~window()
{
    delwin(_header);
    delwin(_output);
    delwin(_input);
    delwin(_friends_list);
    endwin();
}
void window::create_win(WINDOW *&_win,int _h,int _w,int _y,int _x)
{
    _win = newwin(_h,_w,_y,_x);
    box(_win,0,0);
}
void window::create_header()
{
    int _h = LINES/5;
    int _w = COLS;
    int _x = 0;
    int _y = 0;
    create_win(_header,_h,_w,_y,_x);
}
void window::create_output()
{
    int _h = (LINES*3)/5;
    int _w = (COLS*3)/4;
    int _x = 0;
    int _y = LINES/5;
    create_win(_output,_h,_w,_y,_x);
}
void window::create_input()
{
    int _h = LINES/5;
    int _w = COLS;
    int _x = 0;
    int _y = (LINES*4)/5;
    create_win(_input,_h,_w,_y,_x);
}
void window::create_friends_list()
{
    int _h = (LINES*3)/5;
    int _w = COLS/4;
    int _x = (COLS*3)/4;
    int _y = LINES/5;
    create_win(_friends_list,_h,_w,_y,_x);
}
void window::put_str_to_window(WINDOW *_win,int _y,int _x,std::string str)
{
    mvwaddstr(_win,_y,_x,str.c_str());
}
void window::get_str_window(WINDOW *_win,std::string &msg)
{
    char buf[1024];
    wgetnstr(_win,buf,sizeof(buf));
    msg = buf;
}
void window::fflush(WINDOW *_win)
{
    wrefresh(_win);
}
//以下为本模块测试代码
//int main()
//{
//  window win;
//  win.create_header();
//  wrefresh(win._header);
//  usleep(2000000);
//  win.create_output();
//  wrefresh(win._output);
//  usleep(2000000);
//  win.create_friends_list();
//  wrefresh(win._friends_list);
//  usleep(2000000);
//  win.create_input();
//  std::string str = "Please Entry#";
//  mvwaddstr(win._input,1,1,str.c_str());
//  wrefresh(win._input);
//  usleep(2000000);
//  int j = 1;
//  int _y;
//  int _x;
//  while(1)
//  {
//      std::string str = "Welcome to chat_room!";
//      win.create_header();
//      mvwaddstr(win._header,1,j++,str.c_str());
//      if(str.size() >= _x-j-1)
//          j = 1;
//      wrefresh(win._header);
//      getmaxyx(win._header,_y,_x);
//      j%=(_x-1);
//      wclrtoeol(win._header);
//      usleep(100000);
//      
//  }
//  int i = 1;
//  int y;
//  int x;
//  while(1)
//  {
//      std::string str = "Please Entry#";
//      mvwaddstr(win._output,i++,1,str.c_str());
//      wrefresh(win._output);
//      getmaxyx(win._output,y,x);
//      i%=(y-1);
//      if(i == 0)
//      {
//          i = 1;
//          wclrtoeol(win._output);
//          win.create_output();
//
//      }
//      usleep(1000000);
//  }
//
//  return 0;
//}

client端

#ifndef _CLIENT_H_
#define _CLIENT_H_
#include<iostream>
#include<string>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include"window.h"
#include"data.h"
#include"log.h"
#include<vector>
#include<signal.h>
using namespace std;
class client
{
public:
    client(string ip,int port);
    ~client();
    int sock_init();
    int recvmsg(string &out);
    int  sendmsg(const string &out);
private:
    string _ip;
    int _port;
    int _sock;
    //map<int struct sockaddr_in> _onlineusr;
};
#endif
#include"udp_client.h"
client::client(string ip,int port)
    :_ip(ip)
    ,_port(port)
    ,_sock(-1)
{}
client::~client()
{
    if(_sock > 0)
        close(_sock);
}
int client::sock_init()
{
    _sock = socket(AF_INET,SOCK_DGRAM,0);
    if(_sock < 0)
    {
        print_log("socket error",ERROR);
        return -1;
    }
    return 0;
}
int client::recvmsg(string &out)
{
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        char buf[1024];
        ssize_t s = recvfrom(_sock,buf,sizeof(buf)-1,0,\
                            (struct sockaddr*)&peer,&len);
        if(s > 0)//recv success
        {
            buf[s] = 0;
            out = buf;
            return 0;
        }
        return -1;
}
int client::sendmsg(const string &in)
{
    struct sockaddr_in peer;
    peer.sin_family = AF_INET;
    peer.sin_port = htons(_port);
    peer.sin_addr.s_addr = inet_addr(_ip.c_str());
    if(sendto(_sock,in.c_str(),in.size(),0,(struct sockaddr*)&peer,sizeof(peer)))
    {
        return 0;
    }
   return -1;
}
#include"udp_client.h"
string name;
string school;
client *pcli;
vector<string> flist;
int flag = 1;
typedef struct win_cli
{
    client *_cli;
    window *_win;
} win_cli,*pwin_cli;
void add_user(string friends)
{
    int i = 0;
    for(; i < flist.size();++i)
    {
        if(flist[i] == friends)
        {
            flag = 0;
            return;
        }
    }
    flist.push_back(friends);
    flag = 1;
}
void del_user(string friends)
{
    vector<string>::iterator iter = flist.begin();
    while(iter != flist.end())
    {
        if(*iter == friends)
        {
            iter = flist.erase(iter);
            flag = 1;
            break;
        }
        iter++;
    }
}
void quit(int sig)
{
    data _data;
    _data.nick_name = name;
    _data.school = school;
    _data.msg = "";
    _data.cmd = "QUIT";
    string in;
    _data.val_to_serialize(in);
    pcli->sendmsg(in);
    endwin();
    exit(0);
}
void *show_header(void *arg)
{
    pwin_cli wc = (pwin_cli)arg;
    window *win = wc->_win;
    int j = 1;
    int _y;
    int _x;
    while(1)
    {
        string str = "Welcome to chat_room!";
        win->create_header();
        mvwaddstr(win->_header,1,j++,str.c_str());
        if(str.size() >= _x-j-1)
            j = 1;
        wrefresh(win->_header);
        getmaxyx(win->_header,_y,_x);
        j%=(_x-1);
        wclrtoeol(win->_header);
        usleep(100000);

    }
}
void *show_output(void *arg)
{
    pwin_cli wc = (pwin_cli)arg;
    client *cli = wc->_cli;
    window *win = wc->_win;
    int i = 1;
    int j = 1;
    int y;
    int x;
    int fy;
    int fx;
    win->create_output();
    wrefresh(win->_output);
    win->create_friends_list();
    wrefresh(win->_friends_list);
    string out;
    string friends;
    data _d;
    string str;
    while(1)
    {
        cli->recvmsg(out);
        _d.val_to_unserialize(out);
        str=_d.nick_name;
        str+="-";
        str+=_d.school;
        friends = str;
        str+="#";
        str+=_d.msg;
        if(strcmp(_d.cmd.c_str(),"QUIT") == 0)
        {
            del_user(friends);
            wclrtoeol(win->_friends_list);
            wrefresh(win->_friends_list);
            win->create_friends_list();
            wrefresh(win->_friends_list);
        }
        else
        {
            win->put_str_to_window(win->_output,i++,1,str);
            wrefresh(win->_output);
            add_user(friends);
            getmaxyx(win->_output,y,x);
            i%=(y-1);
            if(i == 0)
            {
                i = 1;
                wclrtoeol(win->_output);
                win->create_output();
                wrefresh(win->_output);
            }
        }
            if(flag)
            {
                int k = 0;
                getmaxyx(win->_friends_list,fy,fx);
                for(; k < flist.size();++k)
                {
                    mvwaddstr(win->_friends_list,j++,1,flist[k].c_str());
                    wrefresh(win->_friends_list);
                    j %= (fy-1);
                    if(j == 0)
                    {
                        j = 1;
                        wclrtoeol(win->_friends_list);
                        wrefresh(win->_friends_list);
                        win->create_friends_list();
                        wrefresh(win->_friends_list);
                    }
                }
                j = 1;
        }


    }
}
void *show_input(void *arg)
{
    pwin_cli wc = (pwin_cli)arg;
    client *cli = wc->_cli;
    window *win = wc->_win;
    data _data;
    _data.nick_name = name;
    _data.school = school;
    while(1){
        win->create_input();
        wrefresh(win->_input);
        string ptr = "Please Entry#";
        mvwaddstr(win->_input,1,1,ptr.c_str());
        wrefresh(win->_input);
        win->get_str_window(win->_input,_data.msg);
        wrefresh(win->_input);
        _data.cmd = "";
        string in;
        _data.val_to_serialize(in);
        cli->sendmsg(in);
    }
}
int main(int argc,char *argv[])
{
    if(argc != 3)
    {
        cout << "Usage :" << argv[0] << "[ip]" << "[port]" << std::endl;
        return -1;
    }
    client cli(argv[1],atoi(argv[2]));
    cout << "Please Enteryour nick_name#";
    cin >> name;
    cout << "Please Enter your school#";
    cin >> school;
    cli.sock_init();
    window win;
    win_cli _wc = {&cli,&win};
    pcli = &cli;
    signal(2,quit);
    pthread_t header;
    pthread_t output;
    pthread_t input;
    pthread_create(&input,NULL,show_input,(void*)&_wc);
    pthread_create(&header,NULL,show_header,(void*)&_wc);
    pthread_create(&output,NULL,show_output,(void*)&_wc);
    pthread_join(header,NULL);
    pthread_join(output,NULL);
    pthread_join(input,NULL);

}
//以下为本模块测试代码
//int main(int argc,char *argv[])
//{
//  if(argc != 3)
//  {
//      cout << "Usage :" << argv[0] << "[ip]" << "[port]" << std::endl;
//      return -1;
//  }
//  client cli(argv[1],atoi(argv[2]));
//  cli.sock_init();
//    data _data;
//  cout << "Please Enteryour nick_name#";
//      cin >> _data.nick_name;
//      cout << "Please Enter your school#";
//      cin >> _data.school;
//  while(1)
//  {
//      cout << "please input*";
//      cin >> _data.msg;
//      _data.cmd = "";
//      string in;
//      _data.val_to_serialize(in);
//      cli.sendmsg(in);
//      string out;
//      cli.recvmsg(out);
//      cout << "out:" << out << endl;
//      _data.val_to_unserialize(out);
//      string str;
//          str+=_data.nick_name;
//          str+="-";
//  str+=_data.school;
//  str+="# ";
//  str+=_data.msg;
//      cout << str << endl;
//
//  }
//}

makefile编写

ROOT=$(shell pwd)
LOG=${ROOT}/log
POOL=${ROOT}/data_pool
SERVER=${ROOT}/server
CLIENT=${ROOT}/client
SERVER_BIN=chat_system
CLIENT_BIN=chat_client
BIN=${ROOT}/lib
DATA=${ROOT}/comm
WINDOW=${ROOT}/window
CONF=${ROOT}/conf
PLUGIN=${ROOT}/plugin
INCLUDE=-I$(LOG) -I$(POOL) -I$(BIN)/include -I$(DATA) -I$(WINDOW)
SERVER_OBJ=$(shell ls $(SERVER)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
SERVER_OBJ+=$(shell ls $(LOG)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
SERVER_OBJ+=$(shell ls $(DATA)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
SERVER_OBJ+=$(shell ls $(POOL)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
CLIENT_OBJ=$(shell ls $(CLIENT)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
CLIENT_OBJ+=$(shell ls $(LOG)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
CLIENT_OBJ+=$(shell ls $(DATA)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
CLIENT_OBJ+=$(shell ls $(WINDOW)/ | grep -E '\.cpp$$' | sed 's/\.cpp/\.o/')
cc=g++
FLAGS=-lpthread
.PHONY:all
all:${SERVER_BIN} ${CLIENT_BIN}

${SERVER_BIN}:${SERVER_OBJ}
    @${cc} -o $@ $^ $(FLAGS) -L$(BIN)/lib -ljsoncpp
    @echo "linking [$^] [$@] ....done"

${CLIENT_BIN}:${CLIENT_OBJ}
    @${cc} -o $@ $^ -L$(BIN)/lib -ljsoncpp -lncurses
    @echo "linking [$^] [$@] ....done"

%.o:$(SERVER)/%.cpp
    @$(cc) -c $< $(INCLUDE)
    @echo "comping  [$^] [$@] ....done"

%.o:$(LOG)/%.cpp
    @$(cc) -c $< 
    @echo "comping  [$^] [$@] ....done"

%.o:$(POOL)/%.cpp
    @$(cc) -c $< $(INCLUDE) 
    @echo "comping  [$^] [$@] ....done"

%.o:$(CLIENT)/%.cpp
    @$(cc) -c $< $(INCLUDE)
    @echo "comping  [$^] [$@] ....done"
%.o:$(DATA)/%.cpp
    @$(cc) -c $< $(INCLUDE)
    @echo "comping  [$^] [$@] ....done"
%.o:$(WINDOW)/%.cpp
    @$(cc) -c $< $(INCLUDE)
    @echo "comping  [$^] [$@] ....done"
.PHONY:output
output:
    @mkdir -p outut/server
    @mkdir -p output/server/log
    @mkdir -p output/client
    @cp $(SERVER_BIN) output/server/
    @cp $(CLIENT_BIN) output/client/
    @cp $(PLUGIN)/ctl_server.sh  output/server/
    @cp -rf $(CONF) output/server
.PHONY:clean
clean:
    @rm -rf *.o $(SERVER_BIN) $(CLIENT_BIN) output

成果展示
这里写图片描述
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux小项目-群聊系统 的相关文章

  • 程序运行时数据保存位置

    程序运行时 xff0c 内存中有六个地方可以保存数据 1 寄存器 这是最快的保存区域 xff0c 寄存器位于处理器内部 然而寄存器的数量很有限 xff0c 所以寄存器是根据需要由编译器的分配的 我们对此没有直接的控制权限 也不可能在我们的程
  • ESP-Drone无人机控制板设计的第一个任务---绘制ESP32-S2-WROVER模块及周边电路

    第1步 xff0c 查看官方ESP Drone无人机ESP32 S2 WROVER模块的参考设计原理图 第二步 xff0c 用KiCAD绘制ESP32 S2 WROVER模块及周边电路 1 如图2 1所示 xff0c 从KiCAD的原理图符
  • ROS学习——读取摄像头数据image

    在ROS工作空间的src文件夹下创建read camera功能包 xff0c 并在包内创建include launch src cfg四个文件夹 在cfg文件夹中创建param yaml文件 xff0c 并写入以下内容 xff1a imag
  • ROS学习——控制小车转向

    给定一个旋转的角度 xff0c 让小车进行顺时针或逆时针旋转 span class token macro property span class token directive keyword include span span clas
  • PID参数设定

    在电机的控制领域 xff0c 不同的电机有不同的驱动方式 xff0c 其中应用最广泛的就是PID proportion integration differentiation 控制 P I和D分别指比例控制 xff0c 积分控制和微分控制
  • 系统编程__2__父子进程的创建和回收

    系统编程 这里写的是对于小白来说更多的了解系统编程的文章 xff0c 有写的不对的地方还恳请各位大佬指出错误 xff0c 小编一定会多多采纳 手动多谢 那么 xff0c 上一次我们稍微了解了一下关于系统编程的一些主要内容 没有看到的童鞋还请
  • php解决跨域访问

    php跨域问题解决判断 参考文章 xff1a php跨域 xff1a https blog csdn net ouxiaoxian article details 89332027 预检请求是什么 xff1a https www jians
  • 动态库与静态库的区别是什么

    区别 xff1a 1 静态库的扩展名一般为 a 或 lib xff1b 动态库的扩展名一般为 so 或 dll 2 静态库在编译时会直接整合到目标程序中 xff0c 编译成功的可执行文件可独立运行 xff1b 动态库在编译时不会放到连接的目
  • Ubuntu 使用 du 查看某个文件夹大小

    在 Ubuntu 系统中 xff0c 你可以使用 du 命令来查看文件夹的大小 例如 xff0c 如果你想查看文件夹 var log 的大小 xff0c 你可以使用如下的命令 xff1a du sh var log 其中 xff0c s 选
  • 无人机六旋翼数学建模[matlab-simulink]

    写在前面 xff0c 这篇文章是借鉴Drexel University 的Senior Design project的matlab simulink四旋翼模型 xff0c 在此基础上针对六旋翼进行的基本改进 xff0c 这里只对 43 型模
  • stm32连接DHT11温湿度传感器

    目录 1 DHT11简介 1 1 连接电路 1 2 串行接口 单线双向 2 cubeMX设置 3 代码开发 3 1 实现定时函数 3 2 打开串口调试 3 4 测试代码实现 4 运行效果 1 DHT11简介 1 1 连接电路 信息如下 xf
  • STM32CubeMX 真的不要太好用

    STM32CubeMX 真的不要太好用 由于工作内容的变动 xff0c 我已经很久没有正经的玩过单片机了 xff0c 近期又要用它做个小玩意了 xff0c 还是选 stm32 吧 xff0c 外设库开发不要太方便 xff0c 哈哈哈 先去
  • ESP-Drone控制板设计的第二个任务-绘制USB-TTL串口下载电路和ESP32-S2芯片内置USB接口电路

    1 摘要 ESP32系列处理器一般会需要采用串口来下载代码 xff0c 因此在其设计中都会保留一个USB TTL串口电路 xff0c 查看乐鑫官网的参考设计 xff0c 基本上是采用CP2102这颗USB转TTL串口芯片 xff0c 但在本
  • Airflow ETL任务调度工具 介绍

    Airflow 是 Apache 基金会的一套用于创建 管理和监控工作流程的开源平台 xff0c 是一套非常优秀的任务调度工具 截至2022年7月 xff0c 在GitHub上已经拥有近27k的star 本文主要介绍一下Airflow 2
  • Data_web(八)mysql增量同步到mongodb

    1 mongdb连接 连接方式如下 xff08 重要 xff01 xff01 xff01 xff01 xff0c 账号密码必须建立在db下面 xff0c 如果默认再admin下面 xff0c 导致无法切换库 xff0c 连接报错 xff09
  • 2021电子设计竞赛飞控视觉之openmv寻找方格中心

    写在前面 这是我在电赛飞控备赛期间写的一个小函数 xff0c 功能是寻找目标点所在方格的中心 这样四旋翼在方格地图上移动一定距离之后就可以使用openmv将四旋翼辅助定位至目前所在方格的中心 今年G题刚出来的时候本来以为能用上这个函数进行辅
  • centos6.5vim基本配置

    简单的vim配置 xff1a 在目录 etc 下面 xff0c 有个名为vimrc的文件 xff0c 这是系统中公共的vim配置文件 xff0c 对所有用户都有效 而在每个用户的主目录下 xff0c 都可以自己建立私有的配置文件 xff0c
  • atexit注册函数

    函数名 atexit 头文件 include lt stdlib h gt 功 能 注册终止函数 即main执行结束后调用的函数 用 法 int atexit void func void 注意 xff1a 按照ISO C的规定 xff0c
  • Linux管道的容量大小及管道的数据结构

    一 管道容量 xff1a 我们通过ulimit a 命令查看到的pipo size定义的是内核管道缓冲区的大小 xff0c 这个值的大小是由内核设定的 xff1b 而pipe capacity指的是管道的最大值 xff0c 即容量 xff0
  • 线程初体验

    线程的概念 xff1a 线程是一个进程地址空间的一个控制流程 xff0c 是调度的基本单位 xff0c 由于同一进程的多个线程共享同一地址空间 因此Text Segment Data Segment都是共享的 如果定义一个函数 在各线程中都

随机推荐

  • 死锁的四个必要条件

    死锁产生的四个必要条件 互斥条件 xff1a 资源是独占的且排他使用 xff0c 进程互斥使用资源 xff0c 即任意时刻一个资源只能给一个进程使用 xff0c 其他进程若申请一个资源 xff0c 而该资源被另一进程占有时 xff0c 则申
  • 线程安全与可重入函数的区别

    线程安全 xff1a 一般来讲就是一个代码块被多个并发线程反复调用时会一直产生正确的结果 如何确保线程安全 xff1a 确保线程安全 主要 考虑线程之间共享变量的安全 xff0c 每个线程私有的内容包括 xff1a 线程id xff0c e
  • Linux模拟实现sleep

    工作原理 linux中的sleep函数能够让程序休眠一定的秒数 xff0c 到时间后自动恢复运行 实现思路 设定睡眠的秒数 睡眠 xff08 挂起 xff09 恢复运行实现机制 设定睡眠的秒数 xff1a 采用alarm 函数设定需要睡眠的
  • 基于ESP32C3处理器创建Hello World工程-并使用OpenOCD进行Debug

    1 编程环境 1 1 硬件 序号 名称 描述 备注 1 ESP C3 12F KIT 深圳安信可开发的基于其自家ESP C3 12F模块的开发板 淘宝购买 2 ESP Prog 乐鑫官方推出基于FT2232HL接口芯片的JTAG调试器 淘宝
  • 平衡二叉树旋转详解

    平衡二叉树的定义 xff08 AVL xff09 定义 平衡二叉树或者是一棵空树 xff0c 或者满足以下的性质 xff1a 它的左子树和右子树的高度之差的绝对值不超过1 xff0c 并且左子树和右子树也是一个平衡二叉树 平衡因子 左子树高
  • Linux进程组,作业,会话,作业控制详解

    进程组 xff08 1 xff09 每个进程除了有一个进程id之外还属于进程组 xff0c 进程组是一个或者多个进程的集合 xff0c 通常 xff0c 他们与同一作业相关联 xff0c 可以接收来自同一终端的各种信号 xff08 2 xf
  • 如何写一个linux精灵进程

    什么是精灵进程 精灵进程也称守护进程 xff08 Daemon xff09 xff1a 是运行在后台的一种特殊进程 xff0c 它独立于控制终端并周期性的执行某种任务 xff0c 或等待处理某些发生的事件 Linux大多数服务器就是用精灵进
  • TCP的四种定时器

    TCP使用的四种定时器 xff08 Timer xff09 重传计时器 xff08 Retransmission Timer xff09 坚持计时器 xff08 Persistent Timer xff09 保活计时器 xff08 keep
  • Linux进程池与线程池以及线程池的简单实现

    通过动态创建子进程 xff08 或者子线程 xff09 来实现并发服务器的 这样做有如下缺点 xff1a 1 动态创建进程 xff08 或线程 xff09 是比较耗费时间的 xff0c 这将导致较慢的客户响应 2 动态创建的子进程 xff0
  • linux下vim中多行注释和删除多行注释

    多行注释 xff1a a 按下Ctrl 43 v xff0c 进入列模式 b 在行首选择需要注释的行 c 按下 I xff0c 进入插入模式 xff1b d 然后输入注释符 xff08 等 xff09 e 按下 Esc 键 删除多行注释 x
  • socket编程以及select、epoll、poll示例详解

    socket编程 socket这个词可以表示很多概念 xff0c 在TCP IP协议中 IP地址 43 TCP或UDP端口号 唯一标识网络通讯中的一个进程 xff0c IP 43 端口号 就称为socket 在TCP协议中 xff0c 建立
  • 命令替换的两种方式$()和``

    命令替换的含义 命令替换是指将命令的输出作为命令替换的位置的文本 命令替换的一般作用是抽取一个命令的输出 然后使用 61 操作赋值到一个变量供以后使用 命令替换的两种方式 1 反引号 xff0c 电脑键盘Esc下面的那个键 使用如下图 xf
  • Linux中eval命令

    eval命令的作用 eval命令会首先扫描命令进行所有的替换 xff0c 然后在执行所有的命令 xff0c 该命令适用于那些一次扫描无法实现其功能的变量 xff0c 该命令对变量进行两次扫描 xff0c 这些需要进行两次扫描的变量被称为复杂
  • Shell脚本实现带颜色进度条

    最近刚刚学习啦shell脚本的编程方法 xff0c 就采用shell脚本实现了一个带颜色的进度条 xff0c 下面将结果展示给大家 程序结果 实现这个其实非常的简单 xff0c 只需要了解一些基本的语法就可以了 进度条的实现就是循环加输出格
  • KiCAD绘制原理图的几个常用的操作之一

    摘要 在绘制原理图的的过程中 xff0c 会用到很多的操作功能 xff0c 今天就介绍几个在绘制原理图时必须要用到的几个功能 xff1a 1 放置原理图符号 xff1b 2 放置电源符号 xff1b 3 绘制器件引脚之间的连线 xff1b
  • linux中crond服务与crontab用法详解

    crond服务 crond服务是一种守护进程 xff0c 用来定期执行程序 xff0c 安装完成系统之后 xff0c 默认便会启动此任务调度命令 crond命令每分钟会定期检查是否有要执行的工作 xff0c 如果有要执行的工作便会自动执行该
  • shell字符串截取方法

    运算符截取 1 和 截取字符串 xff08 删左边留右边 xff09 下面我们先看代码和运行结果 解释 xff1a span class hljs keyword var span span class hljs keyword strin
  • 面试题:判断一个节点是否在一棵二叉树中

    题目 xff1a 判断一个节点是否在一棵二叉树中 结点定义如下 span class hljs keyword struct span BinaryTree BinaryTree span class hljs keyword char s
  • shell脚本实现希尔(shell)排序

    题目 xff1a 采用shell脚本实现希尔排序 最近刚刚学习啦shell脚本编程 xff0c 因此写了一个简单的希尔排序 span class hljs shebang bin bash span arr 61 span class hl
  • Linux小项目-群聊系统

    项目名称 xff1a chat room群聊系统背景知识与主要技术 xff1a 熟悉Linux基本指令的使用 xff08 ls cd make mkdir top basename pwd cp mv rm touch xff09 熟悉li