5、消息队列
消息队列保存在内核中,是一个由消息组成的链表。
(1)创建或访问消息队列
int msgget(key_t key,int msgflg);
(2)操作消息队列
int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);
msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小
ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg);
如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值要小于等于msgtype的绝对值。
(3)控制消息队列
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
struct msqid_ds{
struct ipc_perm msg_perm;
…
};
6、Socket
套接字(Socket)是由Berkeley在BSD系统中引入的一种基于连接的IPC,是对网络接口(硬件)和网络协议(软件)的抽象。它既解决了无名管道只能在相关进程间单向通信的问题,又解决了网络上不同主机之间无法通信的问题。
套接字有三个属性:域(domain)、类型(type)和协议(protocol),对应于不同的域,套接字还有一个地址(address)来作为它的名字。
域(domain)指定了套接字通信所用到的协议族,最常用的域是AF_INET,代表网络套接字,底层协议是IP协议。对于网络套接字,由于服务器端有可能会提供多种服务,客户端需要使用IP端口号来指定特定的服务。AF_UNIX代表本地套接字,使用Unix/Linux文件系统实现。
IP协议提供了两种通信手段:流(streams)和数据报(datagrams),对应的套接字类型(type)分别为流式套接字和数据报套接字。流式套接字(SOCK_STREAM)用于提供面向连接、可靠的数据传输服务。该服务保证数据能够实现无差错、无重复发送,并按顺序接收。流式套接字使用TCP协议。数据报套接字(SOCK_DGRAM)提供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使用UDP协议。
一种类型的套接字可能可以使用多于一种的协议来实现,套接字的协议(protocol)属性用于指定一种特定的协议。
(1) 创建套接字
|
int socket(int domain,int type,int protocol); |
对于SOCK_STREAM和SOCK_DGRAM而言,分别只有一种协议支持这种类型的套接字。因此protocol可以为0,表示默认的协议。
(2) 绑定套接字
|
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);//将无名套接字sockfd与addr绑定(bind) |
(3) 监听套接字
|
int listen(int sockfd,int backlog);//backlog限定了等待服务的队列的最大长度 |
(4) 等待接受连接
|
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen); |
当客户端程序尝试连接sockfd套接字时,accept返回一个新的套接字与客户端进行通信。如果addr不是NULL,那么客户端的地址将会保存在addr所指向的结构体中;调用accept()前必须先将addrlen初始化为addr所指向结构体的大小,accept()返回以后,addrlen将会被设置成客户端套接字地址结构体的实际大小。然后,通过对accept()返回的套接字执行read()和write()操作即可实现与客户端的简单的通信。
(5) 建立连接(客户端)
? |
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen); |
connect()在无名套接字sockfd和addr之间建立连接。addr指向的结构体中可以包含服务器的IP地址和端口号等信息。
(6) 数据传输
|
ssize_t send(int sockfd,const void *buf,size_t len,int flags);
ssize_t recv(int sockfd, void *buf, size_t len,int flags); |
(7) 关闭套接字
(8) 主机字节序和网络字节序的转换
|
#include <netinet/in.h>
unsigned long int htonl(unsigned long int hostlong); //host to network,long
unsigned short int htons(unsigned short int hostshort);
unsigned long int ntohl(unsigned long int netlong);
unsigned short int ntohs(unsigned short int netshort); |
long型函数用来转换sockaddr_in.in_addr.s_addr;short型函数用来转换sockaddr_in.sin_port。
今天的讲解就到这里了,想要了解或者学习更多、更详细的内容,欢迎来到我们传智播客C/C++培训专家(
http://www.itcast.cn/c/)来咨询、学习。
本文版权归传智播客C++培训学院所有,欢迎转载,转载请注明作者出处。谢谢!
作者:传智播客C/C++培训学院
首发:http://www.itcast.cn/c/