目录
一、管道
1、pipe()
#include<unistd.h>
int pipe(int fd[2]);
pipe()会建立管道,并将文件描述词由参数 fd 数组返回。
fd[0]为管道里的读取端
fd[1]则为管道的写入端。
返回值: 若成功则返回零,否则返回-1,错误原因存于 errno 中。
2、fork()
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
函数作用:用于创建子进程
函数返回值:会返回两次,一次在父进程中,一次在子进程中,在父进程中返回所创建的子进程的ID,在子进程中返回0
成功:子进程中返回 0,父进程中返回子进程PID
失败:父进程中返回-1,子进程创建失败,无返回值,errorno被设置
失败的两个主要原因:
1. 当前系统的进程数已经达到了系统规定的上限,这时 errno 的值被设置为 EAGAIN
2. 系统内存不足,这时 errno 的值被设置为 ENOMEM
//进程号和进程组相关函数:
pid_t getpid(void); //获取当前进程ID
pid_t getppid(void); //获取当前进程的父进程的ID
pid_t getpgid(pid_t pid); //获取参数pid 指定进程所属的组识别码. 如果参数pid 为0, 则会取得目前进程的组识别码
3、read()和write()
#include <unistd.h>
ssize_t read(int fd,void*buf,size_t count)
参数说明:
fd: 是文件描述符
buf: 为读出数据的缓冲区;
count: 为每次读取的字节数(是请求读取的字节数,读上来的数据保
存在缓冲区buf中,同时文件的当前读写位置向后移)
函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。
返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。若参数count 为0, 则read()不会有作用并返回0。
#include <unistd.h>
ssize_t write(int fd,const void*buf,size_t count);
参数说明:
fd:是文件描述符(write所对应的是写,即就是1)
buf:通常是一个字符串,需要写入的字符串
count:是每次写入的字节数
函数说明:write()会把参数buf所指的内存写入count个字节到参数fd所指的文件内。
返回值:如果顺利write()会返回实际写入的字节数(len)。当有错误发生时则返回-1,错误代码存入errno中。
4、open()和close()
#include <sys/types.h> //这里提供类型pid_t和size_t的定义
#include <sys/stat.h>
#include <fcntl.h>
int open(const char *pathname, int flags);
int open(const char *pathname, int flags, mode_t mode);
参数说明:
pathname: 在open函数中第一个参数pathname是指向想要打开的文件路径名,或者文件名。我们需要注意的是,这个路径名是绝对路径名。文件名则是在当前路径下的。
flags: flags参数表示打开文件所采用的操作,我们需要注意的是:必须指定以下三个常量的一种,且只允许指定一个。
O_RDONLY:只读模式
O_WRONLY:只写模式
O_RDWR:可读可写
以下的常量是选用的,这些选项是用来和上面的必选项进行按位或起来作为flags参数。
O_CREAT 表示如果指定文件不存在,则创建这个文件
mode: mode参数表示设置文件访问权限的初始值,和用户掩码umask有关,比如0644表示-rw-r–r–,也可以用S_IRUSR、S_IWUSR等宏定义按位或起来表示,详见open(2)的Man Page。要注意的是,有以下几点
文件权限由open的mode参数和当前进程的umask掩码共同决定。
第三个参数是在第二个参数中有O_CREAT时才作用,如果没有,则第三个参数可以忽略
#include<unistd.h>
int close(int fd);
功能:关闭一个已经打开的文件
参数说明:
fd:是需要关闭的文件描述符
返回值说明:
成功:返回0;
失败:返回-1,并设置errno
5、 dup()和dup2()
#include <unistd.h>
int dup(int oldfd);
int dup2(int oldfd, int newfd);
功能:将newfd指向oldfd所指的文件,相当于重定向功能。如果newfd已经指向一个已经打开的文件,那么他会首先关闭这个文件,然后在使newfd指向oldfd文件;如果newfd和oldfd指向同一个文件,那么不会关闭,直接返回。
参数说明:oldfd是一个文件描述符
newfd一个文件描述符
返回值:
成功:dup函数返回当前系统可用的最小整数值。
dup2函数返回第一个不小于newfd的整数值,分两种情况:
1. 如果newfd已经打开,则先将其关闭,再复制文件描述符;
2. 如果newfd等于oldfd,则dup2函数返回newfd,而不关闭它。
失败:dup和dup2函数均返回-1,并设置errno。
6、execlp()
#include <unistd.h>
int execlp(const char *filename, const char *arg, ...)
功能:加载一个进程,借助PATH 环境变量
会从PATH环境变量所指得目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当作该文件的argv[0]、argv[1]......,最后一个参数必须用空指针(NULL)结束。
参数:如,ls, date, cp, cat等
返回值:如果执行成功,则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
7、signal()
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
功能:设置某一信号的对应动作。
函数说明:
signal()会依参数signum 指定的信号编号来设置该信号的处理函数。当指定的信号到达时就会跳转到参数handler指定的函数执行。
当一个信号的信号处理函数执行时,如果进程又接收到了该信号,该信号会自动被储存而不会中断信号处理函数的执行,直到信号处理函数执行完毕再重新调用相应的处理函数。但是如果在信号处理函数执行时进程收到了其它类型的信号,该函数的执行就会被中断。
参数说明:
第一个参数signum:指明了所要处理的信号类型,它可以取除了SIGKILL和SIGSTOP外的任何一种信号。
第二个参数handler:描述了与信号关联的动作.
返回值:
返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。
常见信号:
SIGINT 终止进程 中断进程
SIGCHLD 忽略信号 当子进程停止或退出时通知父进程
8、wait()和waitpid()
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
函数说明:
wait()函数用于使父进程(也就是调用wait()的进程)阻塞,直到一个子进程结束或者该进程接收到了一个指定的信号为止。如果该父进程没有子进程或者它的子进程已经结束,则wait()函数就会立即返回。
参数说明:
参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像这样:pid = wait(NULL);
返回值:
如果成功,wait会返回被收集的子进程的进程ID;
如果调用进程没有子进程,调用就会失败,此时wait返回-1,同时errno被置为ECHILD。
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid,int *status,int options);
函数说明:
waitpid()的作用和wait()一样,但它并不一定要等待第一个终止的子进程(它可以指定需要等待终止的子进程),它还有若干选项,如可提供一个非阻塞版本的 wait()功能,也能支持作业控制。实际上,wait()函数只是 waitpid()函数的一个特例,在Linux 内部实现 wait()函数时直接调用的就是waitpid()函数。
从本质上讲,系统调用waitpid和wait的作用是完全相同的,但waitpid多出了两个可由用户控制的参数pid和options,从而为我们编程提供了另一种更灵活的方式。
参数说明:
pid:从参数的名字pid和类型pid_t中就可以看出,这里需要的是一个进程ID。但当pid取不同的值时,在这里有不同的意义。
① pid>0时,只等待进程ID等于pid的子进程,不管其它已经有多少子进程运行结束退出了,只要指定的子进程还没有结束,waitpid就会一直等下去(阻塞在waitpid()函数这里);
② pid=-1时,等待任何一个子进程退出,没有任何限制,此时waitpid和wait的作用一模一样;
③ pid=0时,等待同一个进程组中的任何子进程,如果子进程已经加入了别的进程组,waitpid不会对它做任何理睬;
④ pid<-1时,等待一个指定进程组中的任何子进程,这个进程组的ID等于pid的绝对值;
status:参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL,就像这样:pid = waitpid(-1, NULL, 0);
options:提供了一些额外的选项来控制waitpid,目前在Linux中只支持:WNOHANG和WUNTRACED两个选项,这是两个常数,可以用"|"运算符把它们连接起来使用;比如ret=waitpid(-1,NULL,WNOHANG | WUNTRACED); 如果我们不想使用它们,也可以把options设为0,如ret=waitpid(-1,NULL,0); 如果使用了WNOHANG参数调用waitpid,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去。而WUNTRACED参数,由于涉及到一些跟踪调试方面的知识,加之极少用到,可以自行查阅相关材料。
返回值:
① 当正常返回的时候,waitpid返回收集到的子进程的进程ID;
② 如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;
③ 如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD。
9、unlink()
#include<unistd.h>
int unlink(const char *pathname);
函数功能:即为删除文件。执行unlink()函数会删除所给参数指定的文件。
注意:执行unlink()函数并不一定会真正的删除文件,它先会检查文件系统中此文件的连接数是否为1,如果不是1说明此文件还有其他链接对象,因此只对此文件的连接数进行减1操作。若连接数为1,并且在此时没有任何进程打开该文件,此内容才会真正地被删除掉。在有进程打开此文件的情况下,则暂时不会删除,直到所有打开该文件的进程都结束时文件就会被删除。
参数说明:文件名
返回值:返回值:成功返回0,失败返回 -1
10、memset()
#include<string.h>
void *memset(void *s, int c, size_t n);
功能:memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值。
参数:
s指向要填充的内存块。
c是要被设置的值。
n是要被设置该值的字符数。
返回类型:是一个指向存储区s的指针。
11、mkfifo()
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char * pathname,mode_t mode);
函数说明:在文件系统中创建一个文件,该文件用于提供FIFO功能,即命名管道。
参数说明:
pathname:是将要在文件系统中创建的一个专用文件。
mode:用来规定FIFO的读写权限。
返回值:若成功则返回0,否则返回-1,错误原因存于errno中。
12、exit()和_exit()
#include<stdlib.h>
void exit(int status);
#include <unistd.h>
void _exit(int status);
功能:两者都是终止进程
参数说明:status 是一个整型参数,可以利用这个参数传递 进程结束时的状态,一般来说,exit(0) 表示程序正常退出,exit(1) 或者 exit(-1) 表示程序异常退出。
区别:
_exit()函数的作用是:直接使用进程停止运行,清除其使用的内存空间,并清除其在内核中的各种数据结构;exit()函数则在这一基础上做了一些包装。在执行退出之前加了若干道工序。
exit()函数与_exit()函数最大区别就在于exit()函数在调用exit系统之前要检查文件的打开情况,把文件缓冲区的内容写回文件。
二、system V IPC(消息队列、共享内存、信号量)
缩写 | 全写 | 释义 |
---|---|---|
msg | message (queue) | 消息队列 |
sem | semaphore | 信号量 |
shm | shared memory | 共享内存 |
分类 | 创建函数 | 控制函数 | 独立函数 |
---|---|---|---|
消息队列 | msgget | msgctl | msgsnd,msgrcv |
信号量 | semget | semctl | semop |
共享内存 | shmget | shmctl | shmat,shmdt |
#include <sys/types.h> //公共头文件,声明了key_t类型
#include <sys/ipc.h> //公共头文件
#include <sys/msg.h> //消息队列函数的头文件
#include <sys/sem.h> //信号量函数的头文件
#include <sys/shm.h> //共享内存函数的头文件
1、ftok()
把一个已存在的路径名和一个整数标识符转换成一个key_t值,称为IPC键值(也称IPC key键值)。ftok函数原型及说明如下:
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> |
函数说明 | 把从pathname导出的信息与id的低序8位组合成一个整数IPC键 |
函数原型 | key_t ftok(const char *pathname, int proj_id) |
函数传入值 | pathname:指定的文件,此文件必须存在且可存取 |
proj_id:计划代号(project ID) | |
函数返回值 | 成功:返回key_t值(即IPC 键值) |
出错:-1,错误原因存于error中 | |
附加说明 | key_t一般为32位的int型的重定义 |
分类 | 消息队列 | 共享内存 | 信号量 |
头文件 | #include <sys/types.h> #include <sys/msg.h> | #include <sys/types.h> #include <sys/shm.h> | #include <sys/types.h> #include <sys/sem.h> |
函数原型 | int msgget(key_t key,int msgflg); | int shmget(key_t key, size_t size, int flag); | int semget(key_t key, int nsems, int semflg) |
功能说明 | 用于创建一个新的或打开一个已经存在的消息队列,此消息队列与key相对应。 | 创建共享内存 | 得到一个信号量集标识符或创建一个信号量集对象并返回信号量集标识符 |
参数说明 | key:消息队列关联的键,函数ftok()的返回值或IPC_PRIVATE。 msgflag:消息队列的建立标志和存取权限。 | key: 标识符的规则 size:共享存储段的字节数 flag:读写的权限 | key:所创建或打开信号量集的键。 nsems:创建的信号量集中的信号量的个数,该参数只在创建信号量集时有效。 flag:调用函数的操作类型,也可用于设置信号量集的访问权限,两者通过or表示。 |
返回值 | 成功执行时,返回消息队列标识值。失败返回-1。 | 成功返回共享存储的id,失败返回-1 | 成功:返回信号量集的标识符,出错:-1,错误原因存于error中 |
函数原型 | int msgctl(int msqid int cmd ,struct msqid_ds * buf ) | int shmctl(int shmid, int cmd, struct shmid_ds *buf) | int semctl(int semid, int semnum, int cmd, union semun arg) |
功能说明 | 直接控制消息队列的行为 | 完成对共享内存的控制 | 得到一个信号量集标识符或创建一个信号量集对象并返回信号量集标识符 |
参数说明 | msgqid :消息队列对象的标识符。 cmd:函数要对消息队列进行的操作.IPC_RMID:将队列从系统内核中删除。 buf:消息队列管理结构体,请参见消息队列内核结构说明部分 | shmid:共享内存标识符 cmd:IPC_RMID:删除这片共享内存 buf:共享内存管理结构体。具体说明参见共享内存内核结构定义部分 | semid:信号量集标识符 semnum:信号量集数组上的下标,表示某一个信号量 cmd:需要执行的命令,SETVAL //根据semun设定信号的值。 arg: union semun { short val; /*SETVAL用的值*/ struct semid_ds* buf; /*IPC_STAT、IPC_SET用的semid_ds结构*/ unsigned short* array; /*SETALL、GETALL用的数组值*/ struct seminfo *buf; /*为控制IPC_INFO提供的缓存*/ } arg; |
返回值 | 成功:0; 出错:-1,错误原因存于error中 | 成功:0; 出错:-1,错误原因存于error中 | 成功:大于或等于0; 出错:-1,错误原因存于error中 |
2、msgsnd()和msgrcv()
头文件 | #include <sys/types.h> #include <sys/msg.h> | |
函数类型 | int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg) | ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg); |
功能说明 | 将msgp消息写入到标识符为msqid的消息队列 | 从标识符为msqid的消息队列读取消息并存于msgp中,读取后把此消息从消息队列中删除 |
参数说明 | msgid:消息队列标识符 msgp: 发送给队列的消息。msgp可以是任何类型的结构体,但第一个字段必须为long类型,即表明此发送消息的类型,msgrcv根据此接收消息。msgp定义的参照格式如下: struct s_msg{ /*msgp定义的参照格式*/ msgsz:要发送消息的大小,不含消息类型占用的4个字节,即mtext的长度. msgflg: 0:当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列 IPC_NOWAIT:当消息队列已满的时候,msgsnd函数不等待立即返回 IPC_NOERROR:若发送的消息大于size字节,则把该消息截断,截断部分将被丢弃,且不通知发送进程。 | msgid:消息队列标识符 msgp:存放消息的结构体,结构体类型要与msgsnd函数发送的类型相同 msgsz:要接收消息的大小,不含消息类型占用的4个字节 msgtyp: 0:接收第一个消息 >0:接收类型等于msgtyp的第一个消息 <0:接收类型等于或者小于msgtyp绝对值的第一个消息 msgflg: 0: 阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待 IPC_NOWAIT:如果没有返回条件的消息调用立即返回,此时错误码为ENOMSG IPC_EXCEPT:与msgtype配合使用返回队列中第一个类型不为msgtype的消息 IPC_NOERROR:如果队列中满足条件的消息内容大于所请求的size字节,则把该消息截断,截断部分将被丢弃 |
返回值 | 成功:0; 出错:-1,错误原因存于error中 | 成功:实际读取到的消息数据长度 出错:-1,错误原因存于error中 |
3、shmat()和shmdt()
头文件 | #include <sys/types.h> #include <sys/shm.h> | |
函数原型 | void *shmat(int shmid, const void *shmaddr, int shmflg) | int shmdt(const void *shmaddr) |
功能说明 | 连接共享内存标识符为shmid的共享内存,连接成功后把共享内存区对象映射到调用进程的地址空间,随后可像本地空间一样访问 | 与shmat函数相反,是用来断开与共享内存附加点的地址,禁止本进程访问此片共享内存 |
参数说明 | shmid:共享内存标识符 shmaddr:指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置 shmflg:SHM_RDONLY:为只读模式,其他为读写模式 | shmaddr:连接的共享内存的起始地址 |
返回值 | 成功:附加好的共享内存地址 出错:-1,错误原因存于error中 | 成功:0 出错:-1,错误原因存于error中 |
4、semop()
semop(完成对信号量的P操作或V操作) | |
所需头文件 | #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> |
函数说明 | 对信号量集标识符为semid中的一个或多个信号量进行P操作或V操作 |
函数原型 | int semop(int semid, struct sembuf *sops, unsigned nsops) |
函数传入值 | semid:信号量集标识符 |
sops:指向进行操作的信号量集结构体数组的首地址,此结构的具体说明如下: struct sembuf { short semnum; /*信号量集合中的信号量编号,0代表第1个信号量*/ short val;/*若val>0进行V操作信号量值加val,表示进程释放控制的资源 */ /*若val<0进行P操作信号量值减val,若(semval-val)<0(semval为该信号量值),则调用进程阻塞,直到资源可用;若设置IPC_NOWAIT不会睡眠,进程直接返回EAGAIN错误*/ /*若val==0时阻塞等待信号量为0,调用进程进入睡眠状态,直到信号值为0;若设置IPC_NOWAIT,进程不会睡眠,直接返回EAGAIN错误*/ short flag; /*0 设置信号量的默认操作*/ /*IPC_NOWAIT设置信号量操作不等待*/ /*SEM_UNDO 选项会让内核记录一个与调用进程相关的UNDO记录,如果该进程崩溃,则根据这个进程的UNDO记录自动恢复相应信号量的计数值*/ }; | |
nsops:进行操作信号量的个数,即sops结构变量的个数,需大于或等于1。最常见设置此值等于1,只完成对一个信号量的操作 | |
函数返回值 | 成功:返回信号量集的标识符 |
出错:-1,错误原因存于error中 | |
错误代码 | E2BIG:一次对信号量个数的操作超过了系统限制 EACCESS:权限不够 EAGAIN:使用了IPC_NOWAIT,但操作不能继续进行 EFAULT:sops指向的地址无效 EIDRM:信号量集已经删除 EINTR:当睡眠时接收到其他信号 EINVAL:信号量集不存在,或者semid无效 ENOMEM:使用了SEM_UNDO,但无足够的内存创建所需的数据结构 ERANGE:信号量值超出范围 |
三、socket编程
1、atoi()、atol()、atoll()、atoq()
#include <stdlib.h>
int atoi(const char *nptr); //把字符串nptr转换为int。
long atol(const char *nptr); //把字符串nptr转换为long int。
long long atoll(const char *nptr); //把字符串nptr转换为long long int。
long long atoq(const char *nptr); //atoq() is an obsolete name for atoll()
2、socket()
#include<sys/types.h>
#include<sys/socket.h>
int socket(int domain, int type, int protocol);
函数说明:socket用于创建一个socket描述符,它唯一标识一个socket。
参数说明:
domain:协议域,常见的协议组用AF_INET AF_INET6 AF_LOCAL AF_ROUTE,协议族决定了socket的地址类型.
type:指定socket的类型,主要SOCK_STREAM、SOCK_DGRAM、SOCK_RAW;
protocol:用于制定某个协议的特定类型,即type类型中的某个类型。通常某协议中只有一种特定类型,这样protocol参数仅能设置为0;但是有些协议有多种特定的类型,就需要设置这个参数来选择特定的类型。
返回值:成功:socket的编号,为-1表示失败
3、bind()
#include<sys/types.h>
#include<sys/socket.h>
int bind(int socket,sockaddr * address,uint addrlen);
函数说明:将一个地址和一个端口号绑定到一个socket连接上
参数说明:
socket:之前创建的socket。
sockaddr:一个用来存放Ip地址和端口号的结构体
addrlen:上述结构体的长度
返回值:为-1表示失败,若端口被占用,会从新绑定一个随机端口(仍返回失败)
//结构体sockaddr和sockaddr_in
#include <sys/socket.h>
sockaddr的缺点:sa_data把目标地址和端口存在一起
struct sockaddr {
sa_family_t sin_family;//地址族
char sa_data[14]; //前2字节:端口 后4字节:ip地址 后8字节作为填充
};
struct sockaddr_in{
short sin_family;//(地址族)
unsigned short sin_port;/*端口号*/
struct in_addr sin_addr;/*IP 地址*/
unsigned char sin_zero[8];/*Same size as struct sockaddr没有实际意义,只是为了 跟SOCKADDR结构在内存中对齐*/
};
3、listen()
#include<sys/types.h>
#include<sys/socket.h>
int listen(int socket,int maxconn);
函数说明:将一个socket设置为监听状态,专门用来监听的socket叫做master socket。
参数说明:
socket:之前创建的socket
maxconn:最大接收连接数
返回值:失败返回-1,成功返回0
4、accept()
#include<sys/types.h>
#include<sys/socket.h>
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
函数说明:接收一个客户机的连接,返回一个socket,来自客户机的socket叫connected socket。
参数说明:
sockfd:用来监听的socket(master socket)
addr:传出参数,返回链接客户端地址信息,含IP地址和端口号
addrlen:传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小
返回值:成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno
5、send()和sendto()
#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);
函数说明:向对方发送数据。如果sendto后面的两个参数为NULL和0时与send函数的作用是等价得。sendto函数一般用作UDP通信
参数说明:
sockfd: 用于通信的文件描述符。服务器:sockfd为accept返回的通信描述符
buf: 应用缓存,用于存放要发送到数据。可以是任何类型:结构体,int , char,float,字符串
len: buf的大小
flags:一般设置为0,此时send为阻塞式发送
即发送不成功会一直阻塞,直到被某个信号终端终止,或者直到发送成功为止。指定MSG_NOSIGNAL,表示当连接被关闭时不会产生SIGPIPE信号,指定MSG_DONTWAIT 表示非阻塞发送。
dest_addr:目标地址
addrlen:目标地址结构体的长度
返回值:
成功:返回发送的字节数
失败:返回-1 且errno被设置
6、recv()和revform()
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int socket, 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);
函数说明:接受数据。如果recvfrom后面的两个参数为NULL和0时与recv函数的作用是等价得。recvfrom函数一般用作UDP通信
参数说明:
socket:指定接收端套接字描述符;
buf:指向一个缓冲区,该缓冲区用来存放recv函数接收到的数据;
len:指明buf的长度;
flags:一般置为0;
addr:发送方地址(输出参数)
addrlen:发送方地址结构体的长度(输入输出参数)
返回值:失败时,返回值小于0;超时或对端主动关闭,返回值等于0;成功时,返回值是返回接收数据的长度。
7、memcpy()
#include<string.h>
void *memcpy(void *destin, void *source, unsigned n);
函数说明:C/C++语言中的一个用于内存复制的函数。
以source指向的地址为起点,将连续的n个字节数据,复制到以destin指向的地址为起点的内存中。
参数说明:
destin:目标地址
source:源地址
n:数据长度
返回值:类型是void*,是一个指向destin的指针
注意:数据长度(第三个参数)的单位是字节(1byte = 8bit)
8、字节序和ip转换
#include <arpa/inet.h> //包含 sys/socket.h
uint16_t htons(uint16_t hostshort) //短整形 主机字节序 --> 网络字节序
uint32_t htonl(uint32_t hostlong) //长整形 主机字节序 -->网络字节序
uint16_t ntohs(uint16_t netshort) //短整形 网络字节序 -->主机字节序
uint32_t ntohl(uint32_t netlong) //长整形 网络字节序 -->主机字节序
#include <arpa/inet.h>
int inet_pton(int af,const char *src,void *dst) //主机ip地址 -->网络ip字节序,//将点分十进制的ip地址转化为用于网络传输的数值格式
const char* inet_ntop(int af,const void *src,char *dst,socklen_t size) //网络ip字节序 --> 主机ip地址,//将数值格式转化为点分十进制的ip地址格式
注: 主机ip地址是字符串 、网络ip字节序是整形
函数中p和n分别代表表达(presentation)和数值(numeric),地址的表达格式通常是ASCII字符串,数值格式则是存放到套接字地址结构的二进制值。
参数说明:
(1) af : IP协议 AF_INET、AF_INET6
(2) src: 传入参数 十进制的ip地址
(3) dst:大整形ip 存入地址
(4) size:目标存储单元的大小,以免该函数溢出其调用者的缓冲区。如果size太小,不足以容纳表达式结果,那么返回一个空指针,并置为errno为ENOSPC。
返回值:
返回值:若成功则为1,若输入不是有效的表达式则为0,若出错则为-1. //inet_pton
成功返回指向 dst的指针 失败返回空指针 //inet_ntop
8、strcpy()
#include <string.h>
char *strcpy(char *dest, const char *src)
函数说明:
src 所指向的字符串复制到 dest。
需要注意的是如果目标数组 dest 不够大,而源字符串的长度又太长,可能会造成缓冲溢出的情况。
参数说明:
dest: 指向用于存储复制内容的目标数组。
src: 要复制的字符串。
返回值:该函数返回一个指向最终的目标字符串 dest 的指针。
8、strncpy()
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
函数说明:把src所指向的字符串中以src地址开始的前n个字节复制到dest所指的数组中,并返回dest。
注意:
1、当src字符串长度小于n时,则拷贝完字符串后,剩余部分将用空字节填充,直到n个。strncpy不会向dest追加’\0’。如果n<src的长度,只是将src的前n个字符复制到dest的前n个字符,不自动添加'\0',也就是结果dest不包括'\0',需要再手动添加一个'\0'。
2、src和dest所指的内存区域不能重叠,且dest必须有足够的空间放置n个字符
返回值:dest字符串起始地址