您现在的位置是:主页 > news > 万网手机网站/免费信息推广网站
万网手机网站/免费信息推广网站
admin2025/6/26 12:10:33【news】
简介万网手机网站,免费信息推广网站,用wordpress写网页,中国做投资的网站UNIX 域套接字 UNIX 套接字可在用一台机器上实现进程间通信,因为 UNIX 域套接字仅仅复制数据,不执行协议处理,不需要添加或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套…
万网手机网站,免费信息推广网站,用wordpress写网页,中国做投资的网站UNIX 域套接字 UNIX 套接字可在用一台机器上实现进程间通信,因为 UNIX 域套接字仅仅复制数据,不执行协议处理,不需要添加或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套…
sockaddr_un 结构的 sun_path 成员包含一路径名。当我们将以地址绑定至UNIX域套接字时,系统用该路径名创建一类型为S_IFSOCK的文件。该文件仅用于向客户进程告知套接字名字。该文件不能打开,也不能由应用程序用于通信。如果当我们试图绑定地址时,该文件已经存在,那么bind请求失败。当关闭套接字时,并不自动删除该文件,所以我们必须确保在应用程序终止前,对该文件执行解除链接操作。下面例子是实现地址绑定到 UNIX 域套接字:
UNIX 域套接字
UNIX 套接字可在用一台机器上实现进程间通信,因为 UNIX 域套接字仅仅复制数据,不执行协议处理,不需要添加或删除网络报头,无需验证和,不产生顺序号,无需发送确认报文,比因特网域套接字的效率更高。UNIX域套接字提供流和数据报两种接口,UNIX域数据报服务是可靠的,既不会丢失消息也不会传递出错。UNIX域套接字是套接字和管道之间的混合物。为了创建一对非命名的,相互连接的 UNXI 域套接字,用户可以使用socketopair函数。其实现如下:
#include <sys/socket.h>
int socketpair(int domain, int type, int protocol, int sockfd[2]);
/* 返回值:若成功则返回0,出错则返回-1 */
#include "apue.h"
#include <sys/socket.h>/*
* Return a full-duplex "stream" pipe (a UNIX domain socket)
* with the two file descriptors returned in fd[0] and fd[1].
*/
int
s_pipe(int fd[2])
{return(socketpair(AF_UNIX, SOCK_STREAM, 0, fd));
}
命名 UNIX 域套接字
命名 UNIX 域套接字也是针对没有亲缘关系进程之间的通信,它的地址结构和因特网的地址结构不同,其地址结构如下:
struct sockaddr_un{
sa_family_t sun_family; /* AF_UNIX */
char sun_path[108]; /* pathname */
};
sockaddr_un 结构的 sun_path 成员包含一路径名。当我们将以地址绑定至UNIX域套接字时,系统用该路径名创建一类型为S_IFSOCK的文件。该文件仅用于向客户进程告知套接字名字。该文件不能打开,也不能由应用程序用于通信。如果当我们试图绑定地址时,该文件已经存在,那么bind请求失败。当关闭套接字时,并不自动删除该文件,所以我们必须确保在应用程序终止前,对该文件执行解除链接操作。下面例子是实现地址绑定到 UNIX 域套接字:
#include "apue.h"
#include <sys/socket.h>
#include <sys/un.h>int
main(void)
{int fd, size;struct sockaddr_un un;un.sun_family = AF_UNIX;strcpy(un.sun_path, "foo.socket");if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)err_sys("socket failed");size = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);if(bind(fd, (struct sockaddr *)&un, size) < 0)err_sys("bind failed");printf("UNIX domain socket bound\n");exit(0);
}
唯一连接
服务器进程可以使用标准 bind、listen 和 accept 函数,为客户进程安排一个唯一的 UNIX 域连接。客户进程使用 connect 与服务器进程关联;服务器进程接受了 connect 请求后,在服务器进程和客户进程之间就存在了唯一连接。以下是 UNIX 域套接字唯一连接的实现:这些函数可以套用在前面介绍《基于 socket 的编程》的框架中。
#include "apue.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>#define QLEN 10/*
* Create a server endpoint of a connection.
* Return fd if all ok, <0 on error.
*/
int
serv_listen(const char *name)
{int fd, len, err, rval;struct sockaddr_un un;/* create a UNIX domain stream socket */if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)return(-1);unlink(name); /* in case it already exists *//* fill in socket address structure */memset(&un, 0, sizeof(un));un.sun_family = AF_UNIX;strcpy(un.sun_path, name);len = offsetof(struct sockaddr_un, sun_path) + strlen(name);/* bind the name to the descriptor */if(bind(fd, (struct sockaddr *)&un, len) < 0){rval = -2;goto errout;}if(listen(fd, QLEN) < 0) /* tell kernel we're a server */{rval = -3;goto errout;}return(fd);errout:err = errno;close(fd);errno = err;return(rval);
}
#include "apue.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <time.h>
#include <errno.h>#define STALE 30 /* client's name can't be older than this (sec) *//*
* Wait for a client connection to arrive, and accept it.
* We also obtain the client's usr ID from the pathname
* that it must bind before calling us.
* Returns new fd if all ok, <0 on error
*/
int serv_accept(int listenfd, uid_t *uidptr)
{int clifd, len, err, rval;time_t staletime;struct sockaddr_un un;struct stat statbuf;len = sizeof(un);if((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)return(-1); /* often errno=EINTR, if signal caught *//* obtain the client's uid from its calling address */len -= offsetof(struct sockaddr_un, sun_path); /* len of pathname */un.sun_path[len] = 0; /* null terminate */if(stat(un.sun_path, &statbuf) < 0){rval = -2;goto errout;}
#ifdef S_ISSOCK /* not defined fro SVR4 */if(S_ISSOCK(statbuf.st_mode) == 0){rval = -3; /* not a socket */goto errout;}
#endifif((statbuf.st_mode & (S_IRWXG | S_IRWXO)) ||(statbuf.st_mode & S_IRWXU) != S_IRWXU){rval = -4; /* is not rwx------ */goto errout;}staletime = time(NULL) - STALE;if(statbuf.st_atime < staletime ||statbuf.st_ctime < staletime ||statbuf.st_mtime < staletime){rval = -5; /* i-node is too old */ goto errout;}if(uidptr != NULL)*uidptr = statbuf.st_uid; /* return uid of caller */unlink(un.sun_path); /* we're done with pathname now */return(clifd);errout:err = errno;close(clifd);errno = err;return(rval);
}
#include "apue.h"
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>#define CLI_PATH "/var/tmp/" /* +5 fro pid = 14 chars */
#define CLI_PERM S_IRWXU /* rwx for user only *//*
* Create a client endpoint and connect to a server.
* Returns fd if all ok, <0 on error.
*/
int
cli_conn(const char *name)
{int fd, len, err, rval;struct sockaddr_un un;/* create a UNIX domain stream socket */if((fd = socket(AF_UNIX, SOCK_STREM, 0)) < 0)return(-1);/* fill socket address structure with our address */memset(&un, 0, sizeof(un));un.sun_family = AF_UNIX;sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid());len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);unlink(un.sun_path); /* in case it already exits */if(bind(fd, (struct sockaddr *)&un, len) < 0){rval = -2;goto errout;}if(chmod(un.sun_path, CLI_PERM) < 0){rval = -3;goto errout;}/* fill socket address structure with server's address */memset(&un, 0, sizeof(un));un.sun_family = AF_UNIX;strcpy(un.sun_path, name);len = offsetof(struct sockaddr_un, sun_path) + strlen(name);if(connect(fd, (struct sockaddr *)&un, len) < 0){rval = -4;goto errout;}return(fd);errout:err = errno;close(fd);errno = err;return(rval);}
《UNIX高级环境编程》