5、消息隊列
消息隊列保存在內(nèi)核中,是一個由消息組成的鏈表。
(1)創(chuàng)建或訪問消息隊列
int msgget(key_t key,int msgflg);
(2)操作消息隊列
int msgsnd(int msqid,const void *msg,size_t nbytes,int msgflg);
msg指向的結(jié)構(gòu)體必須以一個long int成員開頭,作為msgrcv()的消息類型,必須大于0。nbytes指的是msg指向結(jié)構(gòu)體的大小,但不包括long int部分的大小
ssize_t msgrcv(int msqid,void *msg,size_t nbytes,long msgtype,int msgflg);
如果msgtype是0,就返回消息隊列中的第一個消息;如果是正整數(shù),就返回隊列中的第一個該類型的消息;如果是負數(shù),就返回隊列中具有最小值的第一個消息,并且該最小值要小于等于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系統(tǒng)中引入的一種基于連接的IPC,是對網(wǎng)絡接口(硬件)和網(wǎng)絡協(xié)議(軟件)的抽象。它既解決了無名管道只能在相關進程間單向通信的問題,又解決了網(wǎng)絡上不同主機之間無法通信的問題。
套接字有三個屬性:域(domain)、類型(type)和協(xié)議(protocol),對應于不同的域,套接字還有一個地址(address)來作為它的名字。
域(domain)指定了套接字通信所用到的協(xié)議族,最常用的域是AF_INET,代表網(wǎng)絡套接字,底層協(xié)議是IP協(xié)議。對于網(wǎng)絡套接字,由于服務器端有可能會提供多種服務,客戶端需要使用IP端口號來指定特定的服務。AF_UNIX代表本地套接字,使用Unix/Linux文件系統(tǒng)實現(xiàn)。
IP協(xié)議提供了兩種通信手段:流(streams)和數(shù)據(jù)報(datagrams),對應的套接字類型(type)分別為流式套接字和數(shù)據(jù)報套接字。流式套接字(SOCK_STREAM)用于提供面向連接、可靠的數(shù)據(jù)傳輸服務。該服務保證數(shù)據(jù)能夠?qū)崿F(xiàn)無差錯、無重復發(fā)送,并按順序接收。流式套接字使用TCP協(xié)議。數(shù)據(jù)報套接字(SOCK_DGRAM)提供了一種無連接的服務。該服務并不能保證數(shù)據(jù)傳輸?shù)目煽啃?,?shù)據(jù)有可能在傳輸過程中丟失或出現(xiàn)數(shù)據(jù)重復,且無法保證順序地接收到數(shù)據(jù)。數(shù)據(jù)報套接字使用UDP協(xié)議。
一種類型的套接字可能可以使用多于一種的協(xié)議來實現(xiàn),套接字的協(xié)議(protocol)屬性用于指定一種特定的協(xié)議。
(1) 創(chuàng)建套接字
|
int socket(int domain,int type,int protocol); |
對于SOCK_STREAM和SOCK_DGRAM而言,分別只有一種協(xié)議支持這種類型的套接字。因此protocol可以為0,表示默認的協(xié)議。
(2) 綁定套接字
|
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);//將無名套接字sockfd與addr綁定(bind) |
(3) 監(jiān)聽套接字
|
int listen(int sockfd,int backlog);//backlog限定了等待服務的隊列的最大長度 |
(4) 等待接受連接
|
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen); |
當客戶端程序嘗試連接sockfd套接字時,accept返回一個新的套接字與客戶端進行通信。如果addr不是NULL,那么客戶端的地址將會保存在addr所指向的結(jié)構(gòu)體中;調(diào)用accept()前必須先將addrlen初始化為addr所指向結(jié)構(gòu)體的大小,accept()返回以后,addrlen將會被設置成客戶端套接字地址結(jié)構(gòu)體的實際大小。然后,通過對accept()返回的套接字執(zhí)行read()和write()操作即可實現(xiàn)與客戶端的簡單的通信。
(5) 建立連接(客戶端)
? |
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen); |
connect()在無名套接字sockfd和addr之間建立連接。addr指向的結(jié)構(gòu)體中可以包含服務器的IP地址和端口號等信息。
(6) 數(shù)據(jù)傳輸
|
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) 主機字節(jié)序和網(wǎng)絡字節(jié)序的轉(zhuǎn)換
|
#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型函數(shù)用來轉(zhuǎn)換sockaddr_in.in_addr.s_addr;short型函數(shù)用來轉(zhuǎn)換sockaddr_in.sin_port。
今天的講解就到這里了,想要了解或者學習更多、更詳細的內(nèi)容,歡迎來到我們傳智播客C/C++培訓專家(
http://metathetuscanyresort.com/c/)來咨詢、學習。
本文版權(quán)歸傳智播客C++培訓學院所有,歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明作者出處。謝謝!
作者:傳智播客C/C++培訓學院
首發(fā):http://metathetuscanyresort.com/c/