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;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WangZun233!