我正在尝试使用UDP在Android上创建一个unix域套接字服务器和客户端。我需要客户端向服务器发送一条消息(“hi”),然后从服务器上向客户端发送数据。我已经成功地在两边创建了套接字,并且我能够在服务器上从客户端接收到一条短消息。然而,服务器上的recvfrom(…)没有填充结构体套接字*src_addr,socklen_t*addrlen参数。使用这些src_addr和addrlen的后续sendto消息显然失败(sendto返回-1)。
这是服务器的代码:
int serverSocket = socket(PF_LOCAL, SOCK_DGRAM, 0);
int sendingBufferSize = OUTPUT_BUFFER_SIZE;
setsockopt(serverSocket, SOL_SOCKET, SO_SNDBUF, &sendingBufferSize, sizeof(sendingBufferSize));
struct sockaddr_un server;
memset(&server, 0, sizeof server);
server.sun_family = AF_LOCAL;
// the first byte of sun_path should be '\0' for abstract namespace
const char * socket_name = SOCKET_NAME;
server.sun_path[0] = '\0';
strcpy(server.sun_path + 1, socket_name);
socklen_t sockaddr_len = sizeof(server.sun_family) + strlen(socket_name) + 1;
if (bind(serverSocket, (struct sockaddr *) &server, sockaddr_len) < 0) {
close(serverSocket);
printf("Failed to bind the server socket\n");
return -1;
}
printf("- Socket binding successful on socket path %s len %d\n", &server.sun_path[1], sockaddr_len);
_serverSocket = serverSocket;
后来我收到了来自客户的消息:
int opcode;
_clientAddressLength = sizeof(struct sockaddr_un);
int numOfBytes = recvfrom(_serverSocket, _messageBuffer, INPUT_BUFFER, 0, (struct sockaddr *)&_clientAddress, &_clientAddressLength);
if (numOfBytes != 0)
{
printf("Got a message from client\n");
memcpy(&opcode, _messageBuffer, sizeof(opcode)); // I'm getting what I expected
}
但是_clientAddress为空,并且_clientAddressLength设置为0。
后来
int result = sendto(_serverSocket
, sendBuf
, sendBufSize
, 0
, (const sockaddr*)&_clientAddress
, _clientAddressLength);
返回-1
谢谢你的帮助伙计们!
编辑:
最后,感谢尼古拉·N·费蒂索夫的链接和一些挖掘,我使它工作。我想发布一个固定的、100% 的工作示例,通过 UNIX 域抽象命名空间套接字进行双向 UDP 通信。这是此 http://www.toptip.ca/2013/01/unix-domain-socket-with-abstract-socket.html?m=1 链接的副本,其中包含已修复的错误。对于后代,因为网络上没有足够的关于这个主题的例子。
服务器.cpp
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>`
#define SERVER_SOCKET "#UdsServer" // The # is replaced by 0 for abstract namespace
int main(void)
{
int socket_fd;
struct sockaddr_un server_address, client_address;
int bytes_received, bytes_sent, integer_buffer;
socklen_t address_length = sizeof(server_address.sun_family)+strlen(SERVER_SOCKET );
if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror("server: socket");
return -1;
}
memset(&server_address, 0, sizeof(server_address));
server_address.sun_family = AF_UNIX;
memcpy(server_address.sun_path, SERVER_SOCKET,sizeof(SERVER_SOCKET)-1);// the path is not a C string, and is not NULL turminated
server_address.sun_path[0] = 0;
if (bind(socket_fd,
(const struct sockaddr *) &server_address,
address_length) < 0)
{
perror("server: bind");
close(socket_fd);
return -1;
}
for (;;)
{
bytes_received = recvfrom(socket_fd,
&integer_buffer,
sizeof(integer_buffer),
0,
(struct sockaddr *) &client_address,
&address_length);
if(bytes_received != sizeof(integer_buffer))
{
printf("Error: recvfrom - %d.\n", bytes_received);
} else {
printf("received: %d.\n", integer_buffer);
integer_buffer += 10;
bytes_sent = sendto(socket_fd,
&integer_buffer,
sizeof(integer_buffer),
0,
(struct sockaddr *) &client_address,
address_length);
}
}
close(socket_fd);
return 0;
}
client.cpp
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SERVER_SOCKET "#UdsServer"
#define CLIENT_SOCKET "#UdsClient"
int main(void)
{
int socket_fd;
struct sockaddr_un server_address, client_address;
int bytes_received, bytes_sent, integer_buffer;
socklen_t address_length = sizeof(server_address.sun_family) + strlen(CLIENT_SOCKET);`
if((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror("client: socket");
return -1;
}
memset(&client_address, 0, sizeof(client_address));
client_address.sun_family = AF_UNIX;
memcpy(client_address.sun_path, CLIENT_SOCKET,sizeof(CLIENT_SOCKET )-1 );
client_address.sun_path[0] = 0;
if(bind(socket_fd,
(const struct sockaddr *) &client_address,
address_length) < 0)
{
perror("client: bind");
return -1;
}
memset(&server_address, 0, sizeof(server_address));
server_address.sun_family = AF_UNIX;
memcpy(server_address.sun_path, SERVER_SOCKET,sizeof(SERVER_SOCKET)-1);
server_address.sun_path[0] = 0;
integer_buffer = 1;
for (;;)
{
bytes_sent = sendto(socket_fd,
&integer_buffer,
sizeof(integer_buffer),
0,
(struct sockaddr *) &server_address,
address_length);
bytes_received = recvfrom(socket_fd,
&integer_buffer,
sizeof(integer_buffer),
0,
(struct sockaddr *) &server_address,
&address_length);
if (bytes_received != sizeof(integer_buffer))
{
printf("Error: recvfrom - %d.\n", bytes_received);
return -1;
}
printf("received: %d\n", integer_buffer);
integer_buffer += 1;
sleep(10);
}
close(socket_fd);
return 0;
}
我希望它能有所帮助,如果您看到更多错误,请告诉我
您正在将地址大小参数设置为Internet地址sockaddr_in
的大小,这对于Unix路径来说太小了。
我认为问题是,您没有bind(2)
绑定客户端套接字,因此它没有名称,因此recvfrom(2)
返回地址长度为零。
从此处尝试代码(客户端需要与服务器名称不同的名称)。
我试图创建一个Unix套接字数据报示例。客户端可以流畅地发送和接收消息。在缓冲区长度小于< code>SOCKET_BUFFER_SIZE的情况下,服务器能够做到这一点,否则服务器的输出会在接收的缓冲区显示一些无效字符。 客户代码 服务器的代码 头文件 这是我得到的 奇怪的是,客户端收到了预期的消息,尽管服务器在发送之前没有正确格式化消息。 这是我的预期输出 我该如何解决?
可能还值得注意的是,我使用了的修改版本,专门为unix域填充。
在nodeJS应用程序中,我希望通过其UNIX套接字。我用这个包裹https://mongodb.github.io/node-mongodb-native/?jmp=docs(版本3.1.6),通过这种方式: 此处的文档中引用了URI:https://docs.mongodb.com/manual/reference/connection-string/#unix-域套接字。但在我的例子中,它失
socket_read和socket_recv之间有什么区别?我正在尝试使用PHP套接字,但使用socket_read时收到了以下警告: 请帮帮我!
开发基于Android和iOS的应用程序,需要与运行在同一设备中的服务器进行通信。目前使用TCP环回连接与应用程序和服务器进行通信(应用程序用用户层编写,服务器用C++编写,使用Android NDK) 我想知道用Unix域套接字取代内部通信是否会提高性能?
我试着做一个简单的服务器-客户机套接字通信,但服务器似乎无法正常工作。无论何时发送或接收,我都会收到此错误: 非插座上的插座操作:非插座上的插座操作 奇怪的是,这只会在服务器发送时出现。客户似乎还可以: