Linux系统/网络 笔记

来源:互联网 发布:多玩数据库魔兽3.35 编辑:程序博客网 时间:2024/05/22 12:52
1 内存共享     内存的获取        int fd = shmget(key_t key ,size_t size , int shmflg);    内存的关联        void* shmat(int shmid ,const void* shmaddr , int shmflg);        char *p;         p = (char*) shmat(fd , 0 , 0 );    内存的分离        int shmdt(const void* shmaddr);    内存的控制        int shmctl(int shmid , int cmd , struct shmid_ds* buf);        ret = shmctl(fd, IPC_RMID, NULL);                cmd : IPC_STAT 获取当前状态 返回给参数3                      IPC_SET  设置共享内存2.多路复用        select系统调用    int ret =  select (int  nfds, fd_set* readfds, fd_set* write ,                                             fd_set* exceptfds, struct timeval* timeout );    nfds = 监听的文件描述符最大值+1;    文件描述符集:fd_set        FD_ZERO :清空集合                      RD_ZERO(&read_set);        FD_CLR  :把指定的文集描述符从集合删除  FD_SET(fd ,&read_Set);         FD_SET  :添加指定的文件描述符到集合        FD_ISSET:监测指定的文件描述符是否在集合中    struct timeval{            long tv_sec;    超时 秒设置            long tv_usec ;  超时 微微秒设置        }    监听到 ret > 0         在用 FD_ISSET(fd , &read_set)  监测 fd 是否在文件集合中    3 .信号量        信号量的获取:            int  semget(key_t key , int nsems , int semflg);             返回值为该信号量的标识符            nsmes 需要的信号数目 一般取1;            IPC_CREAT | 权限        信号的初始化            int semctl(int semid , int sem_num , int cmd , ....);            semid 信号的标识符             sem_num 信号量组中的编号  如果只有一个信号 取值为 0            cmd  : SETVAL 表示初始化信号量  具体参数由第四个参数确定                    信号量只能初始化一次                :IPC_RMID  表示删除;            第四个参数:                union semun{                    int  val    : // sETVAL 要设置的值                    struct semid_ds* buf ;    0;                    unsigned short* array ;   0;                }               注意 union semun 联合体需要自己定义    信号量的操作  V——P            int semop(int semid , struct sembuf* sops , unsigned nsops);            sops  是 一个数组, 元素类型为 struct sembuf                     struct sembuf {                        short sem_num ; 只有一个  取0short sem_op ;  // -1,表示P 操作哦                                        // 1 表示V 操作                        short sem_flg ;  0;                    }                   nsops     表示有几个 struct sembuf ;4 线程        同一个进程内的各个线程,能够共享整个进程的全局变量 ,除了线程的局部变量外, 其他资源都是共享的        线程的创建:            pthread_t  pthread_fd;            int  ret  = pthread_create( pthread_t pthread_fd, pthread_att_t* attr ,                                         void*(*start_routine)(void*)  , void* arg );            attr 设置线程的属性   一般取默认 NULL;            start_routine   该线程的处理函数                                 该函数的返回类型和参数类型都是void*            arg  线程处理函数 start_routine 的参数;    : 创建一个线程 : 同时指定该线程的属性 执行函数 执行函数的参数                                         通过参数1返回该线程的标识符        线程的终止               void  pthread_exit(void * retval);                在线程函数内部调用该函数                    终止该线程, 并通过参数retval 返回一个指针                        该指针不能指向该线程的局部变量        等待指定线程的结束         int pthread_join(pthread_t th ,                                 void** thread_return);            thread_return  指向该线程函数的返回值//===================================网络编程==============================================OSI ---- ISO        物理层    比特流      RS-232     网卡         数据链路层    帧(frame)  交换机           网络层     选择最佳的路径到达目的地    路由器        传输层     提供可靠的数据传输服务(监测路由器丢弃的包)  提供重传机制   包的排序        会话层     管理主机之间的会话过程    会话的建立  会话的终止  会话过程的管理        表示层     数据压缩 格式转换   加密          应用层     与应用程序之间通讯        链路层   ARP -----RARP     协议        网络层        传输层        应用层==------------------------------------------------------------------------    对等通信     虚电路    TCP/IP  协议栈==-----------------------------------------------------------------------      封装:   用户数据  ----> app + 数据 ----> TCP+app+数据 ---> IP+TCP+app+数据 ---->以太网首部+IP+TCP+app---网络      解封:       ===-----------------------------------------------------------------------    端口   1-1023  系统           1024 - 49151            49152-65535    端口决定同一台主机IP 分别传送数据给哪个应用程序          ===-------------------------------------------------------------------------链路层  : 最大传输单元   MTU        46-----1500字节        CRC尾部 校对             ICMP    协议         差错的信息的控制  查询信息的控制  ping————》将数据封装成ICMP 协议实现的                                          地址解析无法完成  使用ICMP 协议 查找MAC硬件地址                   ARP    地址解析协议            RARP    反向            IP地址  只是逻辑上的地址  IP--->MAC   地址解析(ARP) ===-----------------------------------------------------------------------以太网帧的格式  :             目的地址  :             源地址    :             帧类型     :     IP数据包(0800)    ARP(0806)    RARP(8035)   3种             硬件类型 :            协议类型 :            硬件地址长度 :            协议地址长度 :            OP      :            发送端以太网地址 :            发送端IP地址  :            目的以太网地址 :            目的IP地址 :===-----------------------------------------------------------------------------1.      ping ----主机名 -----调用函数 gethostbyname()   将主机名转化为一个32位的IP地址             ----iP地址    2.      向目的IP地址发送一个ICMP 的ECHO 包 3.      将主机IP地址转换为48位的硬件地址    在局域网内发送ARP 请求广播  查找主机的硬件地址4.      主机B ARP 协议层接收到主机A 的ARP 请求后 ,将本机的硬件地址添加到应答包  发送ARP应答到主机A 5.      (ARP高速缓存保存 B 地址    B 保存A地址)        发送ICMP 数据包到主机B6.      主机B收到A 的ICMP 包   发送响应包7.      主机A收到B 的ICMP 响应包===-----------------------------------------------------------------------------------====================================TCP/IP =======================================================首部长度为  15*4 = 60 TLL   数据报的生存期    每经过一个路由器TLL 减一   为0 时丢弃  并发送ICMP报文通知源主机协议类型     1 ICMP  2 IGMP    6 TCP  17 UDP     每经过一个路由器 IP报的头部都会发生改变 ===----------------------------------------------------------------------------------------网际校验和      IP首部(不含校验和)反码+ )+0X 1111 ===----------------------------------------------------------------------------------------路由      用源IP与源SubnetMask相与  , 用目的IP 和SubnetMask相与 看看他们是不是相等 在同一局域网中==------------------------------------------------------------------------------------------基于字节流的传输服务   magment  没有边界 面向链接  可靠的传输服务         端到端的校验和缓冲传输            全双工的传输服务提供流量控制功能==------------------------------------------------IP 报文格式  : IP头部 + TCP头部 + TCP 数据TCP 格式  :TCP头部 + TCP 数据 TCP 头部 : 源端口  + 目的端口    (都为16位)====----------------------------------------------远端口 与目的端口  : + IP首部的源IP地址和目的IP地址 唯一确定一个TCP 链接序号 : 报文段的第一个数据字节序号确认号 : ACK ===-----------------------------------------------三次握手 :        A : 发送 序列号为 a  TCP段 给 B;        B :发起链接 序列号为 b  确认号为 a+1 (希望A回复的序列号为a+1)        A :序列号为a+1 , 确认号为b+1 (希望B在回复的序类号 为b+1)  ===------------------------------------------------四次挥手 :  FIN 位 为1        A : 调用close()函数  序号为 X 表示希望B回复时序列号为 Y          B : 回复A 序列号为Y  ACK 为Q希望收到A回复序列号为Q        B : FIN为1  发送断开请求  序列号为 X ACK 为Q (希望A回复序列号为Q)        A : 发送 序列号为Q ACK 为(X+1) 希望B回复序列号为X+1 ;===-----------------------------------------------------差错       端到端的校验和丢包    超时重传     失序      排序号重复数据-----分割成TCP认为最适合发送的数据块 ---发送一个段后---启动定时器---等待确认-----超时重发      TCP 校验发生错误  需要重新传送流量控制 -------- 滑动窗口累积字节  确认机制     慢启动  拥塞==-------------------------------------------------IP 数据 : IP头部  + UDP头部 + UDP数据 =============================================================socket ==========================================app ---socket----[TCP ----IP ---inet]----->>>>>                          |                          |                       内核已实现socket ------用户进程与内核网络协议栈的编程接口sockaddr_in  :        uint8_t   sin_len;        sa_family_t sin_family ;        in_port_t  si_port ;        struct in_addr sin_addr ;        char sin_zero[8];通用地址结构 :    struct sockaddr {        uint8_t   sin_len;        sa_family_t  sin_family ;        char sa_dat[14];    };===------------------------------------------------------------------------------------------------字节序  :        uint32_t  htonl();        uint16_t  htons();#include <netinet/in.h>#include <arpa/inet.h>        inet_addr(char*)    ;           inet_ntoa(struct in_addr  in);===--------------------------socket---------------------------====回射客户服务器          stdin ------->fgets -------TCP客户--->write----->read--->TCP服务器        stdout<------fputs <-------TCP客户<---read ------<write<--TCP服务器int socket(int domain , int type ,  int protcocol);        AF_INET          SOCK_STREAM   SOCK_DGRAM        0 #include <sys/types.h>#include <sys/socket.h>    int  bind (int sock , (struct sockaddr*) &serveraddr , sizeof(struct sockaddr_in));    serveraddr.sin_family = AF_INET ;    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);    serveraddr.sin_addr.s_addr = inet_addr("127.186.0.8");    inet_aton("127.0.89.0", &serveraddr.sin_addr);    serveraddr.sin_port = htons(8000);==--------------------------------------------#include <sys/socket.h>    int listen(int sock , int backlong)    backlong 为监听的数  最大为20  10   5 return  成功为 0  ,失败为 -1 ;==-----------------------------------------被动套接字  : 接收链接  主动套接字   :发送数据int sockfd = accept (int sock , struct sockaddr* addr , socklen_t *addr_len );失败  返回 -1;==-----------------------------------------int connect(int sock , const struct sockaddr* addr , socklen_t addlen);IP地址和端口 决定一个链接  #include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>int inet_aton(const char *cp, struct in_addr *inp);in_addr_t inet_addr(const char *cp);in_addr_t inet_network(const char *cp);char *inet_ntoa(struct in_addr in);struct in_addr inet_makeaddr(int net, int host);in_addr_t inet_lnaof(struct in_addr in);===----------------------------------------------REUSEADDR   用法  消除服务器关闭后马上启动时   TIME_WAIT 状态 ==-----------------------------------------------server 进程实现    pid_t pid ;    pid = fork();    if(pid == -1){          perror(pid);    }else if(pid == 0){        while(1){        }    }ret = read(sock , buff , BUFF_LEN);if(ret == 0){    cout << "捕捉客户端关闭"<< endl;}sock三次握手完成  放到listen队列中  ==-------------------------------------------------------聊天程序    注意僵尸进程的产生==------------------------------------------------------write --> 复制消息到内核 BUFF(内核缓存)---->MSS<MTU-40 ----> IP层 分包------>    ssize_t readn(int fd , void* buff , size_t count ){        size_t  nleft = count ;        ssize_t nread;        char* bufp = (char*)buff;        while(nleft > 0){            if((nread == read (fd , bufp , nleft)) < 0){                if(errno == EINTR )                    continue ;                return -1;            }else if (nread == 0){                return count -nleft ;            }            bufp +=nread ;           nleft -=nread ;                      }    return count ;    } ==----------------------------------------------------#include <arpa/inet.h>uint32_t htonl(uint32_t hostlong);uint16_t htons(uint16_t honsshort);uint32_t ntohl(uint32_t hostlong);uint16_t ntohs(uint16_t honsshort);如果发送的不是字符 而是数的时候  必须将 数转换为网络字节序  htonl();    接收时                       必须将 网络字节序转换为主机字节序 ntohl();ret = read(sockfd , &n , 4);len = ntohl(n);   //将网络字节序转化为主机字节序ret = read(sockfd , buff, len );==----------------struct info {    size_t len;    char* buff[1024]={0};}info;memset(buff , "hellword");info.len = htonl(strlen(buff));ret = write (sockfd , (void*)&info , 4+strlen(buff));==---------------------------------------------------------recv send  readline  getsockname   getpeername  gethostname gethostbyname gethostbyaddrrecv  只能用于套接口 不能用于文件套接字      ret = read (sockfd  , &info.len , 4);    if(ret == -1 && error == EINTR)        continue ;    return ret ;ftp  格式:    readline 只能用于套接口     int ret ;    int nread;    char * bufp = buff;    int nleft = maxline ;    while(1){        ret = recv_peek (sockfd , bufp , nleft );        if(ret < 0){            return ret ;        }        if(ret == 0){            return 0;        }        nread = ret ;        int  i=0;        for(i=0 ; i < nread ; i++){            if(bufp[i] == '\n'){                ret = readn(sockfd , bufp , i+1);                if(ret != i+1){                    exit(EXIT_FAILURE);                }                return ret ;            }                   }    if(nread > nleft )        exit(EXIT_FAILURE);    nleft -= nread ;    ret = readn(sockfd , bufp , nread );    if(ret != nread ){        exit(EXIT_FAILURE);         }    }==----------------------------------------------------------getsockname()   获取本地地址以及端口号getpeername ()  获取链接对方的地址和端口号#include <sys/socket.h>int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#include <sys/socket.h>int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);#include <netdb.h>extern int h_errno;struct hostent *gethostbyname(const char *name);#include <sys/socket.h>       /* for AF_INET */struct hostent *gethostbyaddr(const void *addr,socklen_t len, int type);void sethostent(int stayopen);void endhostent(void);void herror(const char *s);====----------------------------------------------------------------僵死进程的管理控制    #include <signal.h>     sighandler_t signal(int signum, sighandler_t handler);      signal(SIGCHLD, SIG_IGN);       //忽略信号    signal(SIGCHLD, handle_sigchld);    signal(SIGPIPE, SIG_IGN)      当服务器close一个连接时,若client端接着发数据。    根据TCP 协议的规定,会收到一个RST响应,client再往这个服务器发送数据时,    系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。     根据信号的默认处理规则SIGPIPE信号的默认执行动作是terminate(终止、退出),所以client会退出。    若不想客户端退出可以把SIGPIPE设为SIG_IGN     如:    signal(SIGPIPE,SIG_IGN);     这时SIGPIPE交给了系统处理。     服务器采用了fork的话,要收集垃圾进程,防止僵尸进程的产生,可以这样处理:     signal(SIGCHLD,SIG_IGN); 交给系统init去回收。     这里子进程就不会产生僵尸进程了。void handle_sigchld(int sig){    while(waitpid(-1,NULL , WNOHANG(不挂起)) > 0)  //循环 保证所有SIGCHLD 信号都wait     没有子进程返回时  返回-1  导致循环退出    }完美解决僵尸进程==-----------------------------------------------------------------NNUIX 套接字:socketpair(PF_UNIX ,SOCK_STREAM, 0 ,sockfd ) //  可以实现文件套接字 信息的传递#include <sys/types.h>#include <sys/socket.h>ssize_t send(int sockfd, const void *buf, size_t len, int flags);ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,                   const struct sockaddr *dest_addr, socklen_t addrlen);ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags);#include <sys/types.h>#include <sys/socket.h>ssize_t recv(int sockfd, void *buf, size_t len, int flags);ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,                        struct sockaddr *src_addr, socklen_t *addrlen);ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags);====----------------------------------------------------------------------------POSIX 进程的通信:System V 进程间通信:    文件:    文件锁:    管道: pipe    命名管道 FIFE      传输的是字节流没有边界的    信号: signal    消息队列:     内存共享:    信号量:    互斥量:    条件变量:    读写锁:    套接字:==------------------------------------------------------------------------消息队列:    int msgget(key_t  key , int msgflg);    int msgctl(int msgfd , int cmd , struct msgid_ds* buff);===-----------------------------------------------------------------------DMA  控制  cpu----不参与==----------------------------------------------------------------------用户-------发送信息 -----内核-----应用程序cup  MNU + linux逻辑地址 网络内嵌内核  主要防止产生大量的终段 close tcp ip   五种服务器模型段式管理和页式管理逻辑地址空间------》物理地址 分时操作系统-----时间片段的轮转==------------------------------进程三态--------------------VFS  虚拟文件系统创建  -----------------就绪运行------------------调度I/O -----------------等待--------------------------------------------------进程的状态 :    运行----TASK_RUNING     可中断 ---TASK_INTERRUPTBLE    不可中断 ---TASK_UNINTERRUPTBL    暂停 ------TASK_STOPPED    僵死 ------TASK_ZOMBIEps -ef   0 号进程 -----内核进程函数终止的五种状态:            _exit();            exit();0 --- 正常退出1-----异常退出fork();execl();int atexit(void(* function)(void));===============================================emon函数的用法说明:让一个程序后台运行。原型:[c-sharp] view plaincopy    #include <unistd.h>      int daemon(int nochdir, int noclose);      参数:    当 nochdir为零时,当前目录变为根目录,否则不变;    当 noclose为零时,标准输入、标准输出和错误输出重导向为/dev/null,也就是不输出任何信 息,否则照样输出。    返回值:    deamon()调用了fork(),如果fork成功,那么父进程就调用_exit(2)退出,所以看到的错误信息 全部是子进程产生的。如果成功函数返回0,否则返回-1并设置errno。    #include <stdio.h>          #include <stdlib.h>          #include <unistd.h>          #include <fcntl.h>          #include <limits.h>          int main(int argc, char *argv[])          {                      char strCurPath[PATH_MAX];                              if(daemon(1, 1) < 0)                                          {                                                          perror("error daemon.../n");                                                                      exit(1);                                                                              }                                      sleep(10);                                              if(getcwd(strCurPath, PATH_MAX) == NULL)                                                          {                                                                          perror("error getcwd");                                                                                      exit(1);                                                                                              }                                                      printf("%s/n", strCurPath);                                                              return 0;                                                                  }  ==----------------------------------------------------------------------------守护进程  :setsid();     创建一个进程  在子进程中调用setsid();   pid = setsid();            :daemon();      daemon() 已近包含了fork()   pid= daemon(1,1) ,if pid > 0 创建成功会话期   组长=====------------------------------------------------------------------------------- 子进程退出时向父进程发送一个信号   SIGCHLD  ==----------------------------------------------------------------------------- system :   fork------>excel------->waitpid();==--------------------------------------------------------------------------------中断信号  :    signal()    sigaction();    int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);===-------------------------------------------------------------------------------shell:    find :  find -name  "*.*";    grep :  按行查找     awk  :  按列查找    sed  :  编辑 替换     sed  '1,3'                           sed  's/s1/s2/g'==-------------------------------------------------------------------------------共享内存  :ipcs  ---            共享内存被占用的时候 ,不会马上删除。
0 0
原创粉丝点击