我有一个Unix域数据报套接字的模拟器应用程序,它将数据发送到for.ex / var / lib / XYZ的套接字路径。 sendto返回-2,这是由于另一端没有对等点(没有其他的unix domian套接字应用程序正在运行)
我想使用Unix域套接字编写一个数据报客户端/对等应用程序,以从服务器/模拟器(将数据发送到/ var / lib / XYZ)接收数据。
我的代码如下:
#define BUF_SIZE 1024
#define SV_SOCK_PATH "/var/lib/XYZ"
#define SV_SOCK_PATH2 "/var/lib/ABC"
创建Unix域套接字如下:
struct sockaddr_un svaddr, claddr;
....
sfd = socket(AF_UNIX, SOCK_DGRAM, 0);
if (sfd == -1)
printf("socket creation failed");
memset(&claddr, 0, sizeof(struct sockaddr_un));
claddr.sun_family = AF_UNIX;
strncpy(claddr.sun_path, SV_SOCK_PATH2, sizeof(claddr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *) &claddr, sizeof(struct sockaddr_un)) == -1)
printf("bind failed");
/* Construct address of server */
memset(&svaddr, 0, sizeof(struct sockaddr_un));
svaddr.sun_family = AF_UNIX;
strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1);
while(1)
{
int len=sizeof(struct sockaddr_un);
numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, (struct sockaddr*)&svaddr,&len);
if (numBytes == -1)
printf("recvfrom error");
else{
printf("no of bytes received from server: %d",(int)numBytes);
printf("Response %d: %s\n", (int) numBytes, resp);
}
}
remove(claddr.sun_path);
//exit(EXIT_SUCCESS);
}
但是程序没有接收到任何东西...有什么东西错过了吗?
答案 0 :(得分:1)
当涉及到数据报时,没有真正的客户端或服务器。尝试发送的任何一方负责将数据报寻址到另一方。因此,在您的代码中,设置都是错误的。您显然正在尝试引导“服务器”(但实际上不是服务器,而只是另一个对等方)通过svaddr
发送给您,但这不是它的工作方式。
对于数据报AF_UNIX
套接字,发送者需要在sendto
调用中显式指定接收者的地址,或者它需要首先将其套接字connect
插入接收者的地址。 (在后一种情况下,由于通过send
指定了对等地址,因此它可以使用sendto
而不是connect
。)
您不能在recvfrom
呼叫中指定发送对等方的地址。 recvfrom
中的套接字地址参数旨在返回给您发送数据报的地址。从recvfrom
成功返回后,该变量中的任何内容都将被覆盖。
通常构造数据报对等程序的一种方式:“服务器”创建一个众所周知的路径并绑定到该路径,然后“客户端”创建其自己的终结点并绑定到它的 it (构造一个唯一的套接字地址),则客户端可以sendto
服务器的知名套接字。服务器通过使用recvfrom
来获得客户端的地址以及数据报,然后可以使用sendto
以及地址来向客户端返回消息(无需connect
的套接字) )。这在数据报套接字的基本对等方向之上提供了一种客户端-服务器范例。
最后,我应该提到,使用完全指定的路径名通常是一个好主意,以确保两个对等端都使用相同的地址,即使从不同的目录开始也是如此。 (通常,使用AF_UNIX
时,该地址是文件系统中两个对等方之间“集合”的路径名-因此,如果没有完整路径,则在当前工作目录中,“ some_socket”为“ ./some_socket” 。某些系统(例如linux)还支持不需要完整路径的抽象“隐藏”名称空间,但您必须在名称中使用初始的空字节来指定该名称。)