c中的数据报套接字。看起来父进程永远不会绑定

时间:2014-06-10 17:08:35

标签: c sockets ipc datagram

我试图执行以下两个进程的代码。 孩子发送数据报,父母应该接收并打印它 。父进程看起来好像没有绑定(错误:地址已在使用中)。 任何想法?

#include <sys/socket.h>
#include <sys/un.h>
#include <signal.h>
#include <stdio.h>

#define N 9

int main(int argc, char *argv[]) {

int pid,s,n,addrlen; 
char msg[N]; 
struct sockaddr_un addr;

addr.sun_family=AF_UNIX;        
strcpy(addr.sun_path,"test-socket");    // pathname
addrlen=sizeof(addr.sun_family)+strlen(addr.sun_path);

if (!(pid=fork())) {
    printf("child\n");
    s=socket(PF_UNIX,SOCK_DGRAM,0); 
    sleep(3); /* wait for parent to bind */

    sendto(s,"hi parent",9,0,(struct sockaddr*)&addr,addrlen);  
    printf("child sent\n");
    close(s);

    return(0);
}
printf("father\n");
s=socket(PF_UNIX,SOCK_DGRAM,0);
bind(s,(struct sockaddr *)&addr,addrlen);   // error here

n=recvfrom(s,msg,N,0,NULL,NULL);        
if(n<=0){printf("error\n");}
msg[n]='\0'; printf("%s\n",msg);
close(s);
unlink("test-socket");              

return(0);

}

2 个答案:

答案 0 :(得分:1)

为什么不在fork之前绑定?等待一段固定的时间然后发送数据不是一个好主意

答案 1 :(得分:0)

在我的系统上(Mac OS X Snow Leopard)sockaddr_un看起来像这样:

struct  sockaddr_un {
        unsigned char   sun_len;        /* sockaddr len including null */
        sa_family_t     sun_family;     /* [XSI] AF_UNIX */
        char            sun_path[104];  /* [XSI] path name (gag) */
};

假设您的内容类似,那么您对addrlensizeof(addr.sun_family)+strlen(addr.sun_path))的计算是错误的,这会导致使用sendtobind的调用使用不同的路径比你认为你使用的那个 - 它将被截断。

您对bind的调用可能正在创建一个名为test-socke的套接字文件(请注意最后丢失的t)。程序完成后,尝试unlink不存在的文件test-socket。这意味着下次运行程序时,您尝试bind到(test-socke)的文件已经存在,因此bind将以您看到的方式失败。

要解决此问题,您需要确保使用addrlen的正确长度。最简单和最安全的方法可能是使用sizeof(addr)

addrlen = sizeoff(addr);

如果它可用,你也可以使用SUN_LEN,如果你担心的话可能会节省你复制几个字节:

addrlen = SUN_LEN(&addr);

如果您想自己计算正确的长度(例如SUN_LEN不可用),请尝试以下操作:

addrlen = sizeof(addr) - sizeof(addr.sun_path) + strlen(addr.sun_path);

(这是根据我系统上SUN_LEN的定义改编的。)