c中的数据报套接字。看起来父进程永远不会绑定
Posted
技术标签:
【中文标题】c中的数据报套接字。看起来父进程永远不会绑定【英文标题】:datagram sockets in c. looks like parent process never binds 【发布时间】:2014-06-10 17:08:35 【问题描述】:我尝试执行以下两个进程的代码。 孩子发送一个数据报,父母应该接收并打印它 .父进程看起来没有绑定(错误:地址已在使用中)。 有什么想法吗?
#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);
【问题讨论】:
您看起来正在将 9 个字节接收到一个 9 字节缓冲区中,然后在缓冲区末尾 (msg[n]
) 后以空终止一个字节。你能纠正一下,然后再试一次吗?
您不检查来自socket
、bind
或sendto
的返回值。这样做 - 并在记录错误时使用errno
/strerror
- 看看你是否忽略了问题。
绑定命令返回错误:地址已在使用中
【参考方案1】:
为什么不在fork之前绑定呢?等待固定的时间然后发送数据不是一个好主意
【讨论】:
尝试在 fork 之前创建套接字并绑定..没有工作【参考方案2】:在我的系统上(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) */
;
假设您的看起来类似,您对 addrlen
(sizeof(addr.sun_family)+strlen(addr.sun_path)
) 的计算是错误的,这将导致使用它的调用 sendto
和 bind
使用与您认为正在使用的路径不同的路径– 它将被截断。
您对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
的定义。)
【讨论】:
以上是关于c中的数据报套接字。看起来父进程永远不会绑定的主要内容,如果未能解决你的问题,请参考以下文章