- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习套接字编程。以下代码基于示例,旨在演示套接字连接的基础知识。
#include <iostream>
#include <cerrno>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdint.h>
#include <sstream>
#include <stdexcept>
#include <fcntl.h>
#include <cstdio>
#include <sys/un.h>
#include <cstdlib>
#include <sstream>
#define ASSERT( EXPRESSION ) \
{ \
if ( ! ( EXPRESSION ) ) \
{ \
std::ostringstream oss; \
oss << "Expression \"" << #EXPRESSION << "\" failed at line " << __LINE__ \
<< "; errno == " << errno << " (" << strerror( errno ) << ")"; \
throw std::runtime_error( oss.str() ); \
} \
}
int main( int argc, char* argv[] )
{
int ret_val = 0;
int sd;
char socket_pathname[ L_tmpnam ];
try
{
errno = 0;
// Create a socket
sd = socket( AF_LOCAL, SOCK_STREAM, 0 );
ASSERT( sd >= 0 );
ASSERT( NULL != tmpnam( socket_pathname ) );
ASSERT( strlen( socket_pathname ) < sizeof( ((struct sockaddr_un*)0)->sun_path ) - 1 );
// Create socaddr_un, "derived class" of sockaddr.
struct sockaddr_un su;
su.sun_family = AF_LOCAL;
strncpy( su.sun_path + 1, socket_pathname, sizeof( su.sun_path ) );
su.sun_path[ 0 ] = 'Z';
int su_len = SUN_LEN( &su );
su.sun_path[0] = '\0'; // Why???
// bind address to socket.
int result = bind( sd, (struct sockaddr*)&su, su_len );
ASSERT( -1 != result );
std::cout << "Socket pathname: " << socket_pathname << std::endl;
std::cout << "Socket pathname2: " << su.sun_path + 1 << std::endl;
system( "netstat -pa --unix 2>/dev/null | sed -n '/Active UNIX/,/^Proto/p;/a.out/p'" );
}
catch( std::runtime_error& e )
{
std::cout << e.what() << std::endl;
ret_val = 1;
}
if ( sd >= 0 ) close( sd );
remove( socket_pathname );
return ret_val;
}
我不明白为什么 sockaddr_un::sun_path
中设置的文件名需要偏移 1。这是一个奇怪的约定,无论是我正在学习的示例还是其他阅读 Material 解释了这背后的目的。谁能解释一下?
此外,在调用 SUN_LEN()
之前,如果我将 sockaddr_un::sun_path[0]
设置为 \0
,生成的路径名与我的套接字相关联的似乎是一个以 "@"
为前缀的递增数字,例如@00017
、@00018
等。看来 sockaddr_un::sun_path[0]
必须是除 0 之外的某个 ASCII 值 - 为什么会这样?是否期望有任何特定值?如果我将它更改为其他非 NULL 值,它对程序行为没有明显的影响。
最佳答案
答案在以下 Linux 联机帮助页中:
http://man7.org/linux/man-pages/man7/unix.7.html
The
AF_UNIX
(also known asAF_LOCAL
) socket family is used to communicate between processes on the same machine efficiently. Traditionally, UNIX domain sockets can be either unnamed, or bound to a filesystem pathname (marked as being of type socket). Linux also supports an abstract namespace which is independent of the filesystem....
Three types of address are distinguished in the
sockaddr_un
structure:
pathname: a UNIX domain socket can be bound to a null-terminated filesystem pathname using
bind(2)
. When the address of a pathname socket is returned (by one of the system calls noted above), its length isoffsetof(struct sockaddr_un, sun_path) + strlen(sun_path) + 1
andsun_path
contains the null-terminated pathname. (On Linux, the aboveoffsetof()
expression equates to the same value assizeof(sa_family_t)
, but some other implementations include other fields beforesun_path
, so theoffsetof()
expression more portably describes the size of the address structure.)For further details of pathname sockets, see below.
unnamed: A stream socket that has not been bound to a pathname using
bind(2)
has no name. Likewise, the two sockets created bysocketpair(2)
are unnamed. When the address of an unnamed socket is returned, its length issizeof(sa_family_t)
, andsun_path
should not be inspected.abstract: an abstract socket address is distinguished (from a pathname socket) by the fact that
sun_path[0]
is a null byte ('\0'). The socket's address in this namespace is given by the additional bytes insun_path
that are covered by the specified length of the address structure. (Null bytes in the name have no special significance.) The name has no connection with filesystem pathnames. When the address of an abstract socket is returned, the returnedaddrlen
is greater thansizeof(sa_family_t)
(i.e., greater than 2), and the name of the socket is contained in the first(addrlen - sizeof(sa_family_t))
bytes ofsun_path
.
因此,sun_path[0]
用于区分绑定(bind)路径名套接字地址和抽象套接字地址。如果 sun_path[0]
为 0,则地址是抽象的。否则,整个 sun_path
(包括 sun_path[0]
)是一个文件系统路径。
关于c++ - 为什么设置为 sockaddr_un::sun_path[0] 的文件名要偏移 1?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43947721/
struct sockaddr_un serverUNIXAddress; 以下代码在 Mac OS 10.9 下有效,但在 Linux 下无效。它不会死,但从客户端写入服务器,只能在 Mac OS
#define NAME "server" main() { int sock, msgsock, rval; int pid,len; struct sockaddr_un
我正在使用 Unix 域套接字进行一些测试,我可以毫无问题地通过它们进行通信,但是,当我在测试程序的服务器端调用 accept() 时,返回的 struct sockaddr_un 不包含 sun_p
我正在学习套接字编程。以下代码基于示例,旨在演示套接字连接的基础知识。 #include #include #include #include #include #include #inc
我是一名优秀的程序员,十分优秀!