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 ; 只有一个 取0; short 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
- Linux系统/网络 笔记
- 网络层路由系统(linux网络协议栈笔记)
- 系统与网络笔记
- Linux系统网络服务器
- linux系统网络设置
- 网络安装linux系统
- LINUX系统设置网络
- 网络安装linux系统
- Linux系统网络配置
- linux系统-网络设置
- Linux 系统 网络配置
- linux系统/网络编程
- Linux系统网络配置
- linux系统网络配置
- Linux系统网络管理
- 【网络编程笔记】Linux系统常见的网络编程I/O模型简述
- Linux 网络编程笔记
- linux网络编程笔记
- IO五种模式
- 8. String to Integer (atoi)
- HDU 1166 敌兵布阵 线段树入门_单点更新
- iGrimace IG V8 一键新机安装方式;
- 11 算术运算符与算术表达式的项目(1 分离各位数) (2分离整数和小数部分) (3如何买玫瑰) (4玩数字) (5坐标转换)
- Linux系统/网络 笔记
- Gson的使用
- MySQL 添加修改删除列的方法
- CSS清除浮动大全共8种方法(第3条)
- 移动WEB开发之Safari、QQ、UC、360浏览器的私有Meta属性
- @date2016-03-26(软件工程男的日常)
- 在 CentOS7 下用 yum 安装 nginx
- Tomcat性能调优理论
- UIKit简记