#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
int main()
{
int sock;
struct sockaddr sock_name = {AF_UNIX, "Fred"};
socklen_t len=sizeof(struct sockaddr)+5;
if( (sock=socket(AF_UNIX,SOCK_STREAM,0)) ==-1)
{
printf("error creating socket");
return -1;
}
if( bind(sock,&sock_name,len) != 0 )
{
printf("socket bind error");
return -1;
}
close(sock);
return 0;
}
首次运行后,该程序会报告绑定错误。我试图更改sockaddr的名称。它又有效了。但在将它改回&#34; Fred&#34; (在这种情况下),错误继续。存储在内存中的东西我不清楚吗?为什么会发生这种情况,我该如何解决?
我想我发现了这个问题。第一次运行后,我找到了一个名为&#34; Fred&#34;在当前目录中。我删除了文件,我的程序再次运行。为什么bind方法在当前目录中生成文件?
答案 0 :(得分:1)
与Unix域套接字一起使用时,bind(2)
将在指定路径创建一个特殊文件。此文件标识套接字的方式与主机和端口标识TCP或UDP套接字的方式非常相似。就像你不能两次调用bind
来将两个不同的套接字与给定的主机和端口*相关联,你就无法关联多个Unix套接字
但是,当你拨打close(2)
时,为什么文件不会消失?毕竟,关闭TCP套接字会使其绑定的主机和端口可用于其他套接字。**
这是一个很好的问题,简短的回答是,它只是没有。
因此,在绑定之前调用unlink(2)
是习惯性的(至少在示例代码中)。 Beej's IPC guide的Unix域套接字部分有一个很好的example。
*对于Linux内核的版本&gt; = 3.9,这不是exactly true。
** TIME_WAIT
之后或如果您使用SO_REUSEADDR
套接字选项,则立即执行。
修改强>
您说这是您老师的代码,但我建议您使用printf
替换perror
来电:
if( bind(sock,&sock_name,len) != 0 )
{
perror("socket bind error");
return -1;
}
...将打印出bind(2)
所遇到的真正问题的人类可读表示:
$ ./your-example-executable
$ ./your-example-executable
socket bind error: Address already in use
编程并不是那么难以理解!
答案 1 :(得分:0)
成功打开套接字后,它会一直打开,直到它关闭(即使你的程序终止)。
似乎问题代码没有关闭套接字(例如bind()失败)。
两个进程通常不能打开同一个套接字。
每次执行代码时,都是一个新进程,试图打开同一个套接字。
代码需要一个更好的方案来处理错误。
我就是这样做的:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#define MY_FALSE (0)
#define MY_TRUE (-1)
int main()
{
int rCode=0;
int sock = (-1);
char *socketFile = "Fred");
struct sockaddr sock_name = {AF_UNIX, socketFile};
socklen_t len=sizeof(struct sockaddr)+5;
int bound = MY_FALSE;
if((sock=socket(AF_UNIX,SOCK_STREAM,0)) ==-1)
{
printf("error creating socket");
rCode=(-1);
goto CLEANUP;
}
if( bind(sock,&sock_name,len) != 0 )
{
printf("socket bind error");
rCode=(-1);
goto CLEANUP;
}
bound=MY_TRUE;
这个单一的清理工作&#39; area可以用来释放分配的内存,关闭套接字&amp;文件等。
CLEANUP:
if((-1) != sock)
close(sock);
if(bound)
unlink(socketFile);
return 0;
}