Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么unix套接字文件在创建者退出后仍保留?我可以重复使用它吗?_C++_Linux_Sockets_Unix - Fatal编程技术网

C++ 为什么unix套接字文件在创建者退出后仍保留?我可以重复使用它吗?

C++ 为什么unix套接字文件在创建者退出后仍保留?我可以重复使用它吗?,c++,linux,sockets,unix,C++,Linux,Sockets,Unix,我第一次使用unix套接字,偶然发现unix套接字文件无法自动删除的问题。看起来,在我创建了一个套接字之后,我不能仅仅退出一个程序,相反,我应该删除套接字文件 但是,为什么创建套接字文件的程序退出后,它不会被销毁呢?看起来应该有一种方法以某种方式将应用程序连接到这个剩余的文件,或者为什么它仍然存在 下面是一个示例代码(它创建一个unix套接字,然后退出): #包括 #包括 #包括 int CreateSocket(常量字符*文件名){ if(strlen(filename)>sizeof(soc

我第一次使用unix套接字,偶然发现unix套接字文件无法自动删除的问题。看起来,在我创建了一个套接字之后,我不能仅仅退出一个程序,相反,我应该删除套接字文件

但是,为什么创建套接字文件的程序退出后,它不会被销毁呢?看起来应该有一种方法以某种方式将应用程序连接到这个剩余的文件,或者为什么它仍然存在

下面是一个示例代码(它创建一个unix套接字,然后退出):

#包括
#包括
#包括
int CreateSocket(常量字符*文件名){
if(strlen(filename)>sizeof(sockaddr\u un::sun\u path)){
放置(“文件名太长!”);
返回-1;
}
int fdSock=socket(AF_UNIX,SOCK_DGRAM,0);
如果(fdSock==-1){
佩罗(“插座”);
返回-1;
}
sockaddr_un服务器;
server.sun_family=AF_UNIX;
strcpy(server.sun\u路径,文件名);
if(绑定(fdSock,(sockaddr*)和服务器,sizeof(sockaddr_un))=-1){
佩罗(“插座”);
返回-1;
}
返回0;
}

我不能完全理解你的问题。我认为您不了解
socket()
机制。 我会解释的。这里的套接字类似于指针或文件描述符。 有两种不同的程序:服务器和客户端。他们没有依赖性。服务器打开套接字并等待连接。客户端打开自己的套接字,连接到远程地址。服务器处理连接。这两个程序之间发生数据交换,然后(如有必要)终止连接。 下面是TCP/IP最简单的客户端和服务器程序的示例,它们展示了
socket()
机制的工作原理

服务器代码:

void * server (void)
{
    int listenfd, connfd;
    struct sockaddr_in servaddr;
    socklen_t lenkeepalive;
    struct net_pack recvline;
    int i,n;

    listenfd = socket(AF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(PORT);

    bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

    listen(listenfd, LISTENQ);

    int keepalive =1;
    lenkeepalive = sizeof(keepalive);
    if(setsockopt(listenfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, lenkeepalive) < 0)
    {
        perror("server: setsockopt()");
        shutdown(listenfd,SHUT_RDWR);
        close(listenfd);
        exit(EXIT_FAILURE);
    }

    pthread_create (NULL, NULL, (void *)server_send, NULL);

    for(;;)
    {

        if(connfd = accept(listenfd, (SA *) NULL, NULL)>0){
            bzero(&recvline, sizeof(recvline));
            //try get msg from connected client
            while ( (recv(connfd, &recvline, MAXLINE, 0)) > 0)
            {
                printf("server: recvline.msg - %s\n",recvline.msg);
                bzero(&recvline, sizeof(recvline));
                /*
                    ...
                */
                // send answ

                encode(&recvline,"hello2",H); //make a msg

                if(send(connfd, &recvline, (strlen(recvline.msg)+4), MSG_NOSIGNAL); < 0)
                {
                    printf("server_send: send error %d (%s)\n",errno, strerror(errno));
                }

                //discard client connection
                shutdown(connfd,SHUT_RDWR);
                close(connfd);
            }

        }

    }

    // some error occurs    
    perror("server: accept()");
    shutdown(listenfd,SHUT_RDWR);
    close(listenfd);
    return 0;
}
void*服务器(void)
{
int listenfd,connfd;
servaddr中的结构sockaddr_;
socklen_t lenkeepalive;
结构净包装回收线;
inti,n;
listenfd=套接字(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin\u addr.s\u addr=htonl(INADDR\u ANY);
servaddr.sinu端口=htons(端口);
绑定(listenfd,(SA*)&servaddr,sizeof(servaddr));
听(listenfd,LISTENQ);
int keepalive=1;
lenkeepalive=sizeof(keepalive);
if(setsockopt(listenfd,SOL_SOCKET,SO_KEEPALIVE,&KEEPALIVE,lenkeepalive)<0)
{
perror(“服务器:setsockopt()”);
停机(已列出,停机\RDWR);
关闭(listenfd);
退出(退出失败);
}
pthread_create(NULL,NULL,(void*)server_send,NULL);
对于(;;)
{
如果(connfd=accept(listenfd,(SA*)NULL,NULL)>0){
bzero(&recvline,sizeof(recvline));
//尝试从连接的客户端获取消息
而((recv(connfd,&recvline,MAXLINE,0))>0)
{
printf(“服务器:recvline.msg-%s\n”,recvline.msg);
bzero(&recvline,sizeof(recvline));
/*
...
*/
//发送answ
编码(&recvline,“hello2”,H);//生成消息
如果(发送(connfd,&recvline,(strlen(recvline.msg)+4),msg_NOSIGNAL);<0)
{
printf(“服务器发送:发送错误%d(%s)\n)”,errno,strerror(errno));
}
//放弃客户端连接
停机(connfd、SHUT\RDWR);
关闭(connfd);
}
}
}
//出现了一些错误
perror(“服务器:接受()”);
停机(已列出,停机\RDWR);
关闭(listenfd);
返回0;
}
客户端代码

void * client (void)
{
    socklen_t           lenkeepalive;
    int                 sockfd, keepalive, n;
    struct net_pack recvline;       //pack for msg 
    struct sockaddr_in  servaddr;

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {printf("client: socket error %d ( %s )\n ",errno, strerror(errno));}

    keepalive = 1;
    lenkeepalive = sizeof(keepalive);
    if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, lenkeepalive) < 0)
    {
        perror("client: setsockopt()");
        shutdown(sockfd,SHUT_RDWR);
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(PORT);

    if (inet_pton(AF_INET, servip, &servaddr.sin_addr) <= 0)
        printf("client: inet_pton error for %s\r\n", servip);


    if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        printf("client: connect to %s error %d ( %s )\r\n",servip, errno, strerror(errno));
    }
    else
    {
        // send a msg

        encode(&recvline,"hello",H); //make a msg

        n = send(sockfd, &recvline, (strlen(recvline.msg)+4), MSG_NOSIGNAL);
        if(n < 0)
        {printf("client: i cannot send, error %d (%s)\n",errno, strerror(errno));}

        bzero(&recvline, sizeof(recvline));

        //recv data from server
        while( (n = recv(sockfd, &recvline, MAXLINE, 0)) >= 0)
            {
                printf("client: recvline.msg - %s\n",recvline.msg);
                bzero(&recvline, sizeof(recvline));
            }
    }

    // some error occurs
    perror("client: recv()");
    shutdown(sockfd,SHUT_RDWR);
    close(sockfd);

    return 0;
}
void*客户端(void)
{
socklen_t lenkeepalive;
int sockfd,keepalive,n;
struct net_pack recvline;//为消息打包
servaddr中的结构sockaddr_;
if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)
{printf(“客户端:套接字错误%d(%s)\n”,errno,strerror(errno));}
keepalive=1;
lenkeepalive=sizeof(keepalive);
if(setsockopt(sockfd,SOL_SOCKET,SO_KEEPALIVE,&KEEPALIVE,lenkeepalive)<0)
{
perror(“客户端:setsockopt()”);
关闭(sockfd,关闭\RDWR);
关闭(sockfd);
退出(退出失败);
}
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sinu端口=htons(端口);
if(inet\u pton(AF\u inet、servip和servaddr.sin\u addr)=0)
{
printf(“客户端:recvline.msg-%s\n”,recvline.msg);
bzero(&recvline,sizeof(recvline));
}
}
//出现了一些错误
perror(“客户:recv()”);
关闭(sockfd,关闭\RDWR);
关闭(sockfd);
返回0;
}

在您的情况下,应该使用sockaddr_un而不是sockaddr_In,以及一些必要的标志,如
AF_UNIX
SOCK_DGRAM
和其他。

要充当面向连接的服务器,应用程序创建一个套接字,然后绑定它,然后侦听传入的连接

然后,对于每个传入连接,应用程序都会接受它并为其提供服务

每个操作都有一个函数:
socket
bind
listen
accept

此处所有步骤都是必需的,并且必须在同一应用程序中执行。您不能创建绑定套接字,然后让其他程序使用它

面向连接的客户端需要创建套接字,然后调用
connect


面向数据报的通信没有连接,也不使用
侦听
接受
连接

引用W.Richard Stevens的《Sockets Networking API:UNIX®网络编程第1卷第三版》一书中的简短内容;比尔·芬纳;安德鲁·M·鲁道夫

第15章。示例:Unix域套接字的绑定

首先删除路径名。该路径名
void * client (void)
{
    socklen_t           lenkeepalive;
    int                 sockfd, keepalive, n;
    struct net_pack recvline;       //pack for msg 
    struct sockaddr_in  servaddr;

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {printf("client: socket error %d ( %s )\n ",errno, strerror(errno));}

    keepalive = 1;
    lenkeepalive = sizeof(keepalive);
    if(setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, lenkeepalive) < 0)
    {
        perror("client: setsockopt()");
        shutdown(sockfd,SHUT_RDWR);
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(PORT);

    if (inet_pton(AF_INET, servip, &servaddr.sin_addr) <= 0)
        printf("client: inet_pton error for %s\r\n", servip);


    if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
    {
        printf("client: connect to %s error %d ( %s )\r\n",servip, errno, strerror(errno));
    }
    else
    {
        // send a msg

        encode(&recvline,"hello",H); //make a msg

        n = send(sockfd, &recvline, (strlen(recvline.msg)+4), MSG_NOSIGNAL);
        if(n < 0)
        {printf("client: i cannot send, error %d (%s)\n",errno, strerror(errno));}

        bzero(&recvline, sizeof(recvline));

        //recv data from server
        while( (n = recv(sockfd, &recvline, MAXLINE, 0)) >= 0)
            {
                printf("client: recvline.msg - %s\n",recvline.msg);
                bzero(&recvline, sizeof(recvline));
            }
    }

    // some error occurs
    perror("client: recv()");
    shutdown(sockfd,SHUT_RDWR);
    close(sockfd);

    return 0;
}