- 論壇徽章:
- 0
|
附錄 A UNIX 域套接字
UNIX 域套接字以 UNIX 路徑命名。例如,可以將套接字命名為 /tmp/foo。UNIX 域套接字只在一臺(tái)主機(jī)上的進(jìn)程之間通信。UNIX 域中的套接字不會(huì)被視為網(wǎng)絡(luò)協(xié)議的一部分,因?yàn)樗鼈冎挥糜谠谝慌_(tái)主機(jī)上的進(jìn)程之間通信。
套接字類型定義用戶可見的通信屬性。Internet 域套接字提供對(duì) TCP/IP 傳輸協(xié)議的訪問。Internet 域由值 AF_INET 標(biāo)識(shí)。套接字僅與同一域中的套接字交換數(shù)據(jù)。
創(chuàng)建套接字
socket(3SOCKET)
調(diào)用創(chuàng)建指定系列和指定類型的套接字。
s = socket(family, type, protocol);
如果未指定協(xié)議(值 0),則系統(tǒng)將選擇支持所需套接字類型的協(xié)議。將返回套接字句柄(文件描述符)。
系列由 sys/socket.h 中定義的一個(gè)常量指定。名為 AF_suite 的常量指定要在解釋名稱時(shí)使用的地址格式。
下面創(chuàng)建在同一計(jì)算機(jī)內(nèi)部使用的數(shù)據(jù)報(bào)套接字:
s = socket(AF_UNIX, SOCK_DGRAM, 0);
在大多數(shù)情況下,請(qǐng)將 protocol 參數(shù)設(shè)置為 0(即缺省協(xié)議)。
本地名稱綁定
創(chuàng)建套接字時(shí)不帶名稱。只有在套接字綁定到地址之后,遠(yuǎn)程進(jìn)程才能引用此套接字。通信進(jìn)程通過地址連接。 在 UNIX 系列中,連接通常包括一個(gè)或兩個(gè)路徑名。UNIX 系列套接字無(wú)需始終綁定到名稱。如果它們綁定到名稱,則從不會(huì)存在綁定的重復(fù)排序組(如 local pathname 或 foreign pathname)。路徑名不能涉及現(xiàn)有文件。
通過
bind(3SOCKET)
調(diào)用,進(jìn)程可以指定套接字的本地地址。這樣會(huì)創(chuàng)建 local pathname 排序組,而
connect(3SOCKET)
和
accept(3SOCKET)
通過添加地址的遠(yuǎn)程部分來(lái)完成套接字的關(guān)聯(lián)?梢园慈缦路绞绞褂
bind(3SOCKET)
:
bind (s, name, namelen);
套接字句柄為 s。綁定名稱是由支持協(xié)議解釋的字節(jié)字符串。UNIX 系列名稱包含一個(gè)路徑名和一個(gè)系列。本示例說(shuō)明將名稱 /tmp/foo 綁定到 UNIX 系列套接字。
#include
...
struct sockaddr_un addr;
...
strcpy(addr.sun_path, "/tmp/foo");
addr.sun_family = AF_UNIX;
bind (s, (struct sockaddr *) &addr,
strlen(addr.sun_path) + sizeof (addr.sun_family));
確定 AF_UNIX 套接字的大小時(shí)不計(jì)空字節(jié),因此可以使用
strlen(3C)
。
addr.sun_path 中引用的文件名在系統(tǒng)文件名稱空間中創(chuàng)建為套接字。調(diào)用方必須對(duì)創(chuàng)建 addr.sun_path 的目錄具有寫權(quán)限。不再需要文件時(shí),調(diào)用方應(yīng)將其刪除?梢允褂
unlink(1M)
刪除 AF_UNIX 套接字。
建立連接
通常以非對(duì)稱形式建立連接。一個(gè)進(jìn)程用作客戶機(jī),而另一個(gè)進(jìn)程則用作服務(wù)器。服務(wù)器將套接字綁定到與服務(wù)關(guān)聯(lián)的已知地址,并阻塞在套接字上等待連接請(qǐng)求。然后,不相關(guān)的進(jìn)程便可連接到此服務(wù)器?蛻魴C(jī)通過啟動(dòng)到服務(wù)器套接字的連接,向服務(wù)器請(qǐng)求服務(wù)。在客戶端,
connect(3SOCKET)
調(diào)用啟動(dòng)連接。在 UNIX 系列中,此連接可能如下所示:
struct sockaddr_un server;
server.sun.family = AF_UNIX;
...
connect(s, (struct sockaddr *)&server, strlen(server.sun_path)
+ sizeof (server.sun_family));
有關(guān)連接錯(cuò)誤的信息,請(qǐng)參見
連接錯(cuò)誤
。
數(shù)據(jù)傳送
介紹如何傳送數(shù)據(jù)。
關(guān)閉套接字
介紹如何關(guān)閉套接字。
UNIX域流套接字例子:
-----------------------------------------------------------------------------------
UNIX域面向連接
-----------------------------------------------------------------------------------
UNIX域面向連接的服務(wù)器端程序
#includesys/types.h>
#includesys/socket.h>
#includesys/un.h>
......
#define NAME "my_sock"
main()
{
int orig_sock, //服務(wù)器端原來(lái)套接字描述符
new_sock, //新的套接字描述符
clnt_len, //客戶端地址長(zhǎng)度
i; //循環(huán)計(jì)數(shù)器
static struct sockaddr_un clnt_adr, //客戶-服務(wù)器的UNIX地址
serv_adr;
static char buf[128]; //消息緩沖區(qū)
void clean_up(int , char *); //關(guān)閉套接字并刪除例程
if((orig_sock = socket(AF_UNIX,SOCK_STREAM,0)) 0)
{
peeror("generate error");
exit(1);
}
serv_adr.sun_family = AF_UNIX;
strcpy(serv_adr.sun_path,NAME);
unlink(NAME);
if(bind(orig_sock, (struct sockaddr *)&serv_adr,sizeof(serv_adr.sun_family)
+strlen(serv_adr.sun_path)) 0)
{
peeror("bind error");
clean_up(orig_sock,NAME);
exit(2);
}
listen(orig_sock,1);
clnt_len = sizeof(clnt_adr);
if((new_sock = accept (orig_sock,(struct sockaddr *)&clnt_adr,&clnt_len))0)
{
peeror("accept error");
exit (3);
}
for(i =1;i=10;i++)
{
sleep(1);
read(new_sock,buf,sizeof(buf));
printf("%s\n\n",buf);
}
close(new_sock);
clean_up(orig_sock,NAME);
exit(0);
}
void clean_up(int sd,char * the_file)
{
close(sd);
unlink(the_file);
}
UNIX域面向連接的客戶端程序
#includesys/types.h>
#includesys/socket.h>
#includesys/un.h>
......
#define NAME "my_sock"
main()
{
int orig_sock, //客戶端原來(lái)套接字描述符
i; //循環(huán)計(jì)數(shù)器
static struct sockaddr_un serv_adr;
static char buf[10]; //消息緩沖區(qū)
if((orig_sock = socket(AF_UNIX,SOCK_STREAM,0)) 0)
{
peeror("generate error");
exit(1);
}
serv_adr.sun_family = AF_UNIX;
strcpy(serv_adr.sun_path,NAME);
if(connect(orig_sock, (struct sockaddr *)&serv_adr,sizeof(serv_adr.sun_family)
+strlen(serv_adr.sun_path)) 0)
{
peeror("connect error");
exit(1);
}
for(i =1;i=10;i++)
{
sprintf(buf,"c: %d\n\n",i);
write(orig_sock,buf,sizeof(buf));
}
close(orig_sock);
exit(0);
}
Socket (UDP)
-----------------------------------------------------------------------------------
UNIX域無(wú)連接
-----------------------------------------------------------------------------------
服務(wù)器端程序
#includestdio.h>
#includestdlib.h>
#includeunistd.h>
#includestring>
#includesys/types.h>
#includesys/socket.h>
#includesys/un.h>
#define SERVER_FILE "server_socket"
main(void)
{
int orig_sock, //服務(wù)器端原來(lái)套接字描述符
clnt_len, //客戶端地址長(zhǎng)度
i; //循環(huán)計(jì)數(shù)器
static struct sockaddr_un clnt_adr, //客戶-服務(wù)器的UNIX地址
serv_adr;
static char buf[128]; //消息緩沖區(qū)
void clean_up(int , char *); //關(guān)閉套接字并刪除例程
if((orig_sock = socket(AF_UNIX,SOCK_DGRAM,0)) 0)
{
peeror("generate error");
exit(1);
}
serv_adr.sun_family = AF_UNIX;
strcpy(serv_adr.sun_path,SERVER_FLIE); //分配名字
unlink(SERVER_FLIE);
if(bind(orig_sock, (struct sockaddr *)&serv_adr,sizeof(serv_adr.sun_family)
+strlen(serv_adr.sun_path)) 0)
{
peeror("bind error");
clean_up(orig_sock,SERVER_FLIE);
exit(2);
}
for(i =1;i=10;i++)
{
recvfrom(orig_sock,buf,sizeof(buf),0,(struct sockaddr *)&clnt_adr,&clnt_len);
printf("%s\n\n",buf);
}
clean_up(orig_sock,SERVER_FLIE);
exit(0);
}
void clean_up(int sd,char * the_file)
{
close(sd);
unlink(the_file);
}
客戶端代碼
#includestdio.h>
#includestdlib.h>
#includeunistd.h>
#includestring>
#includesys/types.h>
#includesys/socket.h>
#includesys/un.h>
#define SERVER_FILE "server_socket"
main(void)
{
int orig_sock,
i;
static struct sockaddr_un clnt_adr,
serv_adr;
static char buf[128]; //消息緩沖區(qū)
client_flie[15];
void clean_up(int , char *); //關(guān)閉套接字并刪除例程
serv_adr.sun_family = AF_UNIX;
strcpy(serv_adr.sun_path,SERVER_FLIE); //分配名字
if((orig_sock = socket(AF_UNIX,SOCK_DGRAM,0)) 0)
{
peeror("generate error");
exit(1);
}
sprintf(client_file,"%07d_socket",getpid());
clnt_adr.sun_family = AF_UNIX;
strcpy(clnt_adr.sun_path,client_file);
if(bind(orig_sock, (struct sockaddr *)&clnt_adr,sizeof(clnt_adr.sun_family)
+strlen(clnt_adr.sun_path)) 0)
{
peeror("bind error");
exit(2);
}
for(i =1;i=10;i++)
{
sleep(1);
sprintf(buf,"c: %d\n\n",i);
sendto(orig_sock,buf,sizeof(buf),0,(struct sockaddr *)&serv_adr,sizeof(struct sockaddr));
}
clean_up(orig_sock,client_file);
exit(0);
}
void clean_up(int sd,char * the_file)
{
close(sd);
unlink(the_file);
}
本文來(lái)自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u3/95172/showart_2121480.html |
|