avatar

UC代码汇总

pid

#include 
#include 
int main(){
    pid_t pid = getpid();//获取当前程序的进程号
    pid_t ppid = getppid();//获取当前进程的父进程
    printf("当前进程ID%d,父进程ID%d\n",pid,ppid);
    while(1);
    return 0;
}

fork

#include 
#include 
#include 
int main(){
    printf("我是父进程,我的ID是%d\n",getpid());
    printf("我要创建一个子进程\n");
    pid_t pid = fork();//创建一个子进程,
   // printf("我的ID是%d,fork的返回值是%d\n",getpid(),pid);
    if(pid==-1){
        perror("fork");
        return -1;
    }
    else if(pid==0){//子进程运行的代码
        printf("我的ID是%d,我的父进程ID是%d\n",getpid(),getppid());
    }
    else{
        printf("我的ID是%d,我的子进程ID是%d\n",getpid(),pid);
        //sleep(1);
    }
    printf("进程%d要结束了\n",getpid());
    return 0;
}

fork+exit

#include 
#include 
#include 
int i = 1;
void func(void){
    printf("子进程88\n");
    i = 0;
}
int main(){
    pid_t pid = fork();
    if(pid==-1){
        perror("frok");
        return -1;
    }
    if(pid==0){//子进程
        atexit(func);//注册遗言函数
        sleep(5);
        exit(-1);
    }else{//父进程
        while(i){
            sleep(1);
        }
    }
    return 0;
}

exit

//vim exit.c
#include 
#include 
#include 
//遗言函数-进程结束前会调用的函数
void func(int argc,void* argv){
    printf("%d-%s\n",argc,(char*)argv);//类型强转
    printf("%d进程结束了\n",getpid());
}
int main(){
    //注册遗言函数
    int i= 12;
    on_exit(func,"zhaocb好人");
    sleep(2);//模拟进程处理
    exit(-1);
    return 0;
}

wait

  • 等待任意子进程结束
#include 
#include 
#include 
#include 
int main(){
    pid_t pid = fork();//创建子进程
    if(pid==-1){
        perror("fork");
        return -1;
    }
    else if(pid==0){//子进程运行
        printf("子进程开始运行%d\n",getpid());
        sleep(2);
        printf("子进程结束\n");
        exit(-1);
    }else{//父进程运行
        printf("父进程开始运行\n");
        int i = 0;
        pid_t pid1 = wait(&i);//等待任意子进程结束
        printf("i=%d\n",i);//-1`
        printf("子进程%d结束\n",pid1);
        printf("父进程结束\n");
        int t = WIFEXITED(i);//判断是否正常退出
        if(t==0){
            printf("子进程非正常结束\n");
        }else{
            printf("子进程正常结束\n");
        }
        int status = WEXITSTATUS(i);//获取退出状态信息
        printf("退出状态信息为%d\n",status);
    }
    return 0;
}

waitpid

#include 
#include //exit()
#include //fork
#include //wait  waitpid
int main(){
    pid_t pid = fork();
    if(pid==-1){
        perror("fork1");
        return -1;
    }else if(pid==0){//子进程运行
        printf("%d进程运行\n",getpid());
        sleep(2);
        printf("%d进程运行结束\n",getpid());
        exit(-1);
    }else{//父进程运行
        pid_t pid1 = fork();
        if(pid1==-1){
            perror("fork2");
        }else if(pid1==0){
            printf("%d进程运行\n",getpid());
            sleep(5);
            printf("%d进程运行结束\n",getpid());
            exit(-1);
        }
        int i = 0;
        waitpid(pid1,&i,0);
        printf("父进程结束\n");
    }
    return 0;
}

vfork

#include 
#include 
#include 
int i = 0;
int main(){
    //pid_t pid = fork();
    pid_t pid = vfork();//创建一个子进程
    if(pid==-1){
        perror("vfork");
        return -1;
    }else if(pid==0){
        /*
        printf("子:i=%d\n",i);
        i=12;*/
        execl("clear",NULL);
        exit(0);
    }else{
        printf("父:i=%d\n",i);
    }
    return 0;
}

signal

  • 信号

  • #include 
    #include 
    #include 
    #include 
    void fa(int sigia){//信号值
         printf("信号%d被捕获\n",sigia);
         printf("游戏即将结束...\n");
         sleep(1);
         signal(SIGINT,SIG_DFL);
         exit(-1);
    }
    int main(){
        signal(SIGINT,fa);//注册信号处理函数
        int x=0;
        int y=0;
        int dx=1;
        int dy=1;
        while(1){
            if(x>20){
                dx = -1;
            }else if(x<0){
                dx = 1;
            }
            if(y>10){
                dy=-1;
            }else if(y<0){
                dy = 1;
            }
            x+=dx;
            y+=dy;
            int i=0,j=0;
            for(i=0;i

stat

  • 获取文件属性
#include
#include
#include
#include
#include
#include
#include
#include
#include
int main(){
     struct stat buf = {0};//元素结构体  保存文件元数据
    if(stat("./1",&buf) == -1){ //获取元素体
        perror("stat:\n");//打印错误信息
        return -1;
    }
    printf("i节点号:%ld\n",buf.st_ino);
    printf("文件大小%ld\n",buf.st_size);
    //
    char mode[128]={0};
    if(S_ISDIR(buf.st_mode))
        printf("this is a directory");

    if((buf.st_mode&S_IFMT) == S_IFDIR){
        mode[0] = 'd';
    }
    else if((buf.st_mode&S_IFMT) == S_IFREG){
        mode[0] = '-';
    }/*else((buf.st_mode&S_IFMT) == S_IFREG){
        mode[0] = 'x';
    }*/
    //获取用户权限
    mode[1]=buf.st_mode&S_IRUSR?'r':'-'; 
    mode[2]=buf.st_mode&S_IWUSR?'r':'-';
    mode[3]=buf.st_mode&S_IXUSR?'r':'-'; 
    mode[4]=buf.st_mode&S_IRGRP?'r':'-'; 
    mode[5]=buf.st_mode&S_IWGRP?'r':'-'; 
    mode[6]=buf.st_mode&S_IXGRP?'r':'-'; 
    mode[7]=buf.st_mode&S_IROTH?'r':'-'; 
    mode[8]=buf.st_mode&S_IWOTH?'r':'-'; 
    mode[9]=buf.st_mode&S_IXOTH?'r':'-'; 
    mode[10]=' ';

    mode[11] = (buf.st_nlink + 48);
    //属主名
    struct passwd* pusr = getpwuid(buf.st_uid);
    mode[12] = ' ';
    //strcat 拼接字符串
    strcat(mode,pusr->pw_name);
    strcat(mode," ");
    //数组名
    struct group* pgou=getgrgid(buf.st_gid);
    strcat(mode,pgou->gr_name);
    strcat(mode," ");
    //获取文件大小
    char len[16] = {0};
    sprintf(len,"%ld",buf.st_size);
    strcat(mode,len);
    strcat(mode," ");
    //获取最后一次修改时间
    char *ptime = ctime(&buf.st_mtime);
    strcat(mode,ptime);
    strcat(mode," ");
    //获取文件名称
    strcat(mode,"1");
    //打印
    printf("%s\n",mode);
    return 0;
}

dirent

#include
#include
#include
#include
int main(){
    DIR* fd = opendir("./");//打开当前目录
    if(fd == NULL){
        perror("opendir:\n");
        return -1;
    }
    while(1){
        struct dirent* fd1=readdir(fd);
        if(fd1 == NULL){
            break;
        }
        if(fd1->d_type == 4){//目录
            printf("{%s}",fd1->d_name);
        }
        if(fd1->d_type == 8){//文件
            printf("[%s]",fd1->d_name);
        }
    }
    printf("\n");
    closedir(fd);
    fd = NULL;
    return 0;
}

mkfifo

  • 管道文件

    #include
    #include
    #include
    #include
    #include
    //打开管道
    int main(){
         pid_t pid = fork();
         if(pid==-1){(子进程写,父进程读)
               perror("fork");
               return -1;
         }
         if(pid==0){//子进程
                 //1.打开管道文件
               int fd = open("./fifo.p",O_WRONLY);
              if(fd==-1){
                 perror("open");
                return -1;
             }
             //2向管道写入数据
            while(1){
                 char buf[128]={0};
                 scanf("%s",buf);
                write(fd,buf,strlen(buf));
               if(strcmp(buf,"88了")==0){
                   break;
                }
            }
            //3关闭
           close(fd);
        }else{
        //1.打开管道文件
        int fd = open("./fifo.a",O_RDONLY);
        if(fd==-1){
            perror("open");
            return -1;
        }
        //2从管道读取数据
        while(1){
        char buf[128]={0};
        read(fd,buf,sizeof(buf));
        if(strcmp(buf,"88了")==0){
            break;
            }
           printf(">%s\n",buf);
        }
        //3关闭
        close(fd);
    }
        return 0;
    }
    
    #include 
    #include //read write
    #include //open
    #include //mkfifo
    #include //strcmp
    int main(){
        pid_t pid = fork();//创建子进程(子进程向管道写入数据,父进程接受数据)
        if(pid==-1){
             perror("fork");
             return -1;
        }
       if(pid==0){
              //1创建写管道文件
              if(mkfifo("./fifo.a",0664)==-1){
                     perror(mkfifo);
                     exit(-1); 
               }
               //2打开管道文件
              int fd = open("./fifo.a",O_WRONLY) ;
               //3 写入数据
              while(1){
                       char buf[128]={0};
                       scanf("%s\n",buf);
                       write(fd,buf,strlen(buf));
                       if(strcmp(buf,"88了")==0){
                              break;
                      }
              }
              //关闭管道
              close(fd);
              sleep(1);   
        }else{
        //1、创建管道文件
        if(mkfifo("./fifo.p",0664)==-1){
            perror("mkfifo");
            return -1;
        }
        //2、打开文件
        int fp = open("./fifo.p",O_RDONLY);
        if(fp==-1){
            perror("open");
            unlink("./fifo.p");
            return -1;
        }
        //3、读取数据
        while(1){
            char buf[128]={0};
            read(fp,buf,sizeof(buf));
            if(strcmp(buf,"88了")==0){
                break;
            }
            printf(">%s\n",buf);
        }
        //4、关闭
        close(fp);
        sleep(1);
        }
        //5、删除
        unlink("./fifo.p");
        unlink("./fifo.a");
        return 0;
    }

shm

#include 
#include 
#include 
#include 
#include //ftok
#include //shmget shmat shmdt shmctl
int main(){
    //1、获取键值ftok
    key_t key = ftok("./",120);
    if(key == -1){
        perror("ftok");
        return -1;
    }
    printf("key=%d\n",key);//%d\n
    //2、创建共享内存shmget
    int shmId = shmget(key,128,IPC_CREAT|0664);
    if(shmId==-1){
        perror("shmget");
        return -1;
    }
    printf("shmId = %d\n",shmId);//%d\n
    //3、加载共享内存   映射
    char* p = (char*)shmat(shmId,0,0);
    if(p==(char*)-1){
        perror("shmat");
        shmctl(shmId,IPC_RMID,NULL);//销毁内存
        return -1;
    }
    //4、通信
    while(1){
        scanf("%s",p);//%s
        if(strcmp(p,"88了")==0){
            break;
        }
    }
    //5、卸载共享内存  解除
    if(shmdt(p)==-1){
        perror("shmdt");
        1+1;   
    }
    p=NULL;
    //查看共享内存信息
    struct shmid_ds buf={0};
    shmctl(shmId,IPC_STAT,&buf);
    printf("共享内存大小=%d\n",buf.shm_segsz);//%d\n
    printf("加载程序的进程=%d\n",buf.shm_cpid);//%d\n
    //6、销毁共享内存
    shmctl(shmId,IPC_RMID,NULL);
    return 0;
}

msg

  • 发送方
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef struct Msg{
    int type;//消息类型  4
    char buf[128];//数据,传递的消息 128
}Msg;
int msgId=0,flg=1; //IPC标识ID,flg控制while循环
void fa(int sig){//处理ctrl+c,退出聊天室
    Msg msg={0};
    msg.type = 1;
    strcpy(msg.buf,"88了");//将“88了”拷贝到msg.buf的字符串里
    msgsnd(msgId,&msg,sizeof(msg.buf),0);
    msg.type = 2;
    strcpy(msg.buf,"88了");//将“88了”拷贝到msg.buf的字符串里
    msgsnd(msgId,&msg,sizeof(msg.buf),0);
    flg = 0;/*
    signal(SIGINT,SIG_DFL);
    */
    sleep(1);
    //销毁
    msgctl(msgId,IPC_RMID,NULL);
    _Exit(0);
}
int main(){
    signal(SIGINT,fa);
    //1创建键值  ftok
    key_t key = ftok("./",99);
    if(key==-1){
        perror("ftok");
        return -1;
    }
    printf("键值:%d\n",key);//%d\n
    //2创建消息队列 msgget   改
    /*int*/ msgId = msgget(key,IPC_EXCL|IPC_CREAT|0664);
    if(msgId==-1){
        perror("msgget");
        return -1;
    }
    printf("消息队列ID:%d\n",msgId);//%d\n
    //3发送消息或者接受消息msgsnd/msgrcv   改
    while(flg){  //改
        Msg msg={0};
        printf("请输入1或者2表明给进程1和进程2发送消息,3,以及要发送的消息\n");//\n
        scanf("%d%s",&msg.type,msg.buf);//%d%s
        size_t size = sizeof(msg.buf);//求发送数据的长度
        if(msgsnd(msgId,&msg,size/*sizeof(msg.buf)*/,0)==-1){
            break;
        }
        /*  改
        if(strcmp(msg.buf,"88了")==0){
            if(msg.type==3) break;
            else{
                msg.type=3;
                msgsnd(msgId,&msg,sizeof(msg.buf),0);
                break;
            }
        }*/
    }
    //获取消息队列信息
    struct msqid_ds buf={0};
    if(msgctl(msgId,IPC_STAT,&buf)==0){
        printf("队列中的消息数%ld\n",buf.msg_qnum);//%ld\n
        printf("最后一个发送消息的进程%d\n",buf.msg_lspid);//%d\n
    }
    //4销毁队列 msgctl
    msgctl(msgId,IPC_RMID,NULL);
    return 0;
}
  • 接收方
#include 
#include 
#include 
#include 
#include 
#include 
typedef struct Msg{
    int type;//类型
    char buf[128];//消息数据
}Msg;
int main(){
    //1获取键值  ftok
    key_t key = ftok("./",99);
    if(key==-1){
        perror("ftok");
        return -1;
    }
    printf("key=%d\n",key);//%d\n
    //2获取消息队列 msgget
    int msgId = msgget(key,0);
    if(msgId==-1){
        perror("msgget");
        return -1;
    }
    printf("msgid=%d\n",msgId);//%d\n
    //3接受消息,处理消息  msgrcv
    while(1){
        Msg msg={0};
        //接受除消息类型为2以外的其他类型的消息  改
        if(msgrcv(msgId,&msg,sizeof(msg.buf),1,0)!=-1){
            if(strcmp(msg.buf,"88了")==0){
                break;
            }
            printf(">%d-%s\n",msg.type,msg.buf);//>%d-%s\n
        }
    }
    return 0;
}

TCP

  • 服务端
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>//ip地址转换
int Serfd = 0;//接收客户端登录的套接字
int clifds[50]={0};//保存各个客户端的通信描述符
int size = 0;//记录已连接客户端数
int start();
void waitconnect();
void Recv(int);
void Send(char*);
int delete(int);
int start(){
    //1创建socket
    Serfd = socket(AF_INET,SOCK_STREAM,0);          
    if(Serfd==-1){
        perror("socket");
        return -1;
    }
    //2准备通信地址
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8888);
    addr.sin_addr.s_addr=INADDR_ANY;
    //3绑定服务器
    if(bind(Serfd,(struct sockaddr*)&addr,sizeof(addr))==-1){
        perror("bind");
        return -1;
    }
    //4启动监听
    if(listen(Serfd,50)==-1){
        perror("listen");
        return -1;
    }
    return 1;
}
void WaitConnect(){
    while(1){
        //5等待客户端连接
        struct sockaddr_in cli;
        socklen_t len = sizeof(cli);
        int clifd = accept(Serfd,(struct sockaddr*)&cli,&len);
        if(clifd==-1){
            perror("accept");
            continue;
        }
        //6打印客户端信息
        char* ip = inet_ntoa(cli.sin_addr);
        printf("第%d个用户,%s进来\n",size+1,ip);
        char buf[128]={0};
        sprintf(buf,"欢迎%s用户进入聊天室",ip);
        Send(buf);
        clifds[size] = clifd;//将用户socket保存到数组中
        size++;
        //启动子进程
        if(fork==0){
            Recv(clifd);
            exit(-1);
        }
    }
}
//接收消息
void Recv(int fd){
    while(1){
    char buf[128]={0};
    int res = recv(fd,buf,sizeof(buf),0);
        //8接收客户端发送消息
        //9判断消息
        if(res==-1){
            perror("recv");
            continue;
        }else if(res==0){
            delete(fd);
            break;
        }else if(strcmp(buf,"88")==0){
            sleep(1);
            delete(fd);
            break;
        }
        //10转发消息给其他客户端
        Send(buf);
    }
}
//转发消xi
void Send(char* buf){
    int i = 0;
    for(i=0;i<size;i++){
    int res = send(clifds[i],buf,strlen(buf),0);
    }
}
//删除用户
int delete(int clifd){
    int i=0,j=0;
    for(i=0;i<size;i++){
        if(clifds[i]==clifd){
            for(j=i+1;j<size;j++){
                clifds[j-1] = clifds[j];
            }
            size--;
            break;
        }
    }
    Send("欢送xxx退出聊天室\n");
}
int main(){
    printf("服务器即将启动\n");
    if(start()==-1){
        printf("服务器启动失败\n");
        return -1;
    }
    printf("f服务器启动成功\n");
    printf("等待客户端的连接\n");
    WaitConnect();
    return 0;
}
  • 客户端
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<signal.h>
int fd = 0;
int conn(char* ip,int port,char* name){
    //1 创建socket
    fd = socket(AF_INET,SOCK_STREAM,0);
    if(fd==-1){
        perror("socker");
        printf("创建socker失败\n");
        return -1;
    }
    //2 准备通信地址
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    //3 连接服务器
    if(connect(fd,(struct sockaddr*)&addr,sizeof(addr))==-1){
        perror("connect");
        return -1;
    }
    return fd;
}
//发送消息进程
void Send(int fd,char* name ){
    while(1){
        printf(">");
        char buf[128]={0};
        //4 接受用户输入    scanf
        scanf("%s",buf);
        scanf("%*[^\n]");
        scanf("%*c");
        char str[128] = {0};
        sprintf(str,"%s:%s",name,buf);
        //5 发送用户输入的内容
        send(fd,buf,strlen(buf),0);
    }
}
//接收消息进程
void Recv(int fd){
    while(1){
        char buf[128]={0};
        //4 接受服务器发送来的消息
        int res = recv(fd,buf,sizeof(buf),0);
        if(res==-1){
            perror("recv");
            continue;
        }else if(res==0){
            break;
        }
        //5 处理服务器发送来的消息
        printf("<%s\n",buf);
    }
}
void fa(int sig){
    //ctrl+c 向服务器发送88了
    send(fd,"88",4,0);
    printf("客户端即将关闭。。。\n");
    sleep(2);
    exit(-1);
}
int main(int argc,char* argv[]){//./cli 127.0.0.1 5566 name
    signal(SIGINT,fa);
    char ip[20]={0};
    int port = 0;
    char name[32]={0};
    if(argc!=4){
        strcpy(ip,"127.0.0.1");
        port = 5566;
        strcpy(name,"网友A");
    }else{
        strcpy(ip,argv[1]);
        port = atoi(argv[2]);
        strcpy(name,argv[3]);
    }
    printf("客户端即将启动\n");
    int fd = conn(ip,port,name);
    if(fd==-1){
        printf("客户端启动失败\n");
        return -1;
    }
    printf("客户端启动成功\n");
    //创建进程 子进程接收消息,父进程发送消息
    pid_t pid = fork();
    if(pid==-1){
        return -1;
    }else if(pid==0){
        Recv(fd);
    }else{
        Send(fd,name);
    }
    return 0;
}

UDP

  • 服务端
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
//启动服务器
int start(){
    int fd = socket(AF_INET,SOCK_DGRAM,0);
    if(fd==-1){
        perror("socket");
        return -1;
    }
    //1创建socket
    //2准备通信地址
    struct sockaddr_in addr;
    addr.sin_family =AF_INET;
    addr.sin_port = htons(5566);
    addr.sin_addr.s_addr = INADDR_ANY;
    //3绑定
    if(bind(fd,(struct sockaddr*)&addr,sizeof(addr))==-1){
        perror("bind");
        return -1;
    }
    return fd;
}
void Recv(int fd){
    //接收消息
    while(1){
    struct sockaddr_in cli;
    socklen_t len = sizeof(cli);
    char buf[128]={0};
    int res = recvfrom(fd,buf,sizeof(buf),0,(struct sockaddr*)&cli,&len);
    if(res==-1){
        perror("recvfrom");
        continue;
    }else if(res==0){
        printf(">%s登录\n",inet_ntoa(cli.sin_addr));
        continue;
    }
    //5处理消息
    printf(">%s\n",buf);
    //6回复消息
    scanf("%s",buf);
    sendto(fd,buf,strlen(buf),0,(struct sockaddr*)&cli,len);
    }
}
int main(){
    printf("服务器正在启动...\n");
    sleep(1);
    int fd = start();
    if(fd==-1){
        return -1;
    }else{
        printf("服务器启动成功\n");
    }
    Recv(fd);
    return 0;
}
  • 客户端
#include 
#include 
#include 
#include 
#include 
#include 
#include 

typedef struct sockaddr ck;
typedef struct sockaddr_in in;

int main(){
    //1.创建socket
    int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(sockfd == -1){
        perror("socket:");
        printf("socket创建失败\n");
        return -1;
    }
    //2.准备通信地址
    in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(5566);
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //3.准备发送消息
    while(1){
        char buf[128] = {0};
        scanf("%s",buf);
        //4.发送消息
        if(sendto(sockfd,buf,sizeof(buf),0,(ck*)&addr,sizeof(addr)) == -1){
            perror("send:");
            printf("发送失败\n");
            break;            
        }
    //5.准备接收服务器
        if(recvfrom(sockfd,buf,sizeof(buf),0,NULL,NULL) == -1){
            perror("recvform:");
            printf("接收失败\n");
            break;
        }
    //6.处理服务器响应
        printf(">%s\n",buf);
    }
    return 0;
}
文章作者: wangzun233
文章链接: https://wangzun233.top/2020/12/17/UC%E4%BB%A3%E7%A0%81%E6%B1%87%E6%80%BB/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WangZun233