我正在努力使這個簡單的溝通工作。如何使用unix套接字(AF_UNIX,SOCK_DGRAM)模擬PUB/SUB?
我在不到五分鐘的時間裏用zmq做了它。 用UNIX套接字做這件事很痛苦(顯然是因爲我缺乏自信)。
這是服務器:
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "streamsocket.h"
char *socket_path = "/tmp/stream";
int socket_fd=0;
struct sockaddr_un addr;
int main(){
socket_setup();
while(1){
socket_sendstr("a");
sleep(1);
}
}
void socket_setup(){
int rc;
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strcpy(addr.sun_path, socket_path);
if ((socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) {
perror("socket error");
exit(-1);
}
rc=bind(socket_fd, (struct sockaddr *) &addr, sizeof(addr));
if(rc<0){
perror("bind error");
exit(-2);
}
}
int socket_sendstr(char* buffer) {
int len=strlen(buffer);
// corrected after suggestion in answer below (rc->len)
// int rc=write(socket_fd, buffer, rc);
int rc=write(socket_fd, buffer, len);
if (rc != len) {
if (rc > 0) fprintf(stderr,"partial write");
else {
perror("write error");
//exit(-1);
}
}
}
這是客戶端:
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
char * server_filename = "/tmp/stream";
char * client_filename = "/tmp/stream-client";
struct sockaddr_un server_addr;
struct sockaddr_un client_addr;
int rc;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sun_family = AF_UNIX;
strncpy(server_addr.sun_path, server_filename, 104);
memset(&client_addr, 0, sizeof(client_addr));
client_addr.sun_family = AF_UNIX;
strncpy(client_addr.sun_path, client_filename, 104);
// get socket
int sockfd = socket(AF_UNIX, SOCK_DGRAM, 0);
// bind client to client_filename
rc = bind(sockfd, (struct sockaddr *) &client_addr, sizeof(client_addr));
if(rc==-1) perror("bind error");
// connect client to server_filename
rc = connect(sockfd, (struct sockaddr *) &server_addr, sizeof(server_addr));
if(rc==-1) perror("connect error");
char buf[1024];
int bytes=0;
while(bytes = read(sockfd, buf, sizeof(buf))){
printf("%s\n",buf);
}
close(sockfd);
}
我做錯了嗎?
目前客戶端不打印任何東西。
EDIT1:正確的錯誤 「RC」 的服務器寫(,RC)寫(,,LEN)
EDIT2:作爲客戶端不socat工作之一: socat UNIX的客戶:/ tmp目錄/流 -
所以我認爲這個問題可能在服務器上。
是的,服務器說enpoint沒有連接,但是它在啓動任何客戶端之前也說過,所以我想這是因爲沒有連接任何客戶端。所以,沒有辦法做「盲流」(就像在zeromq PUB或UDP組播中一樣),唯一的辦法就是「接受和回覆」連接。 – d3k
在Unix數據報套接字上沒有廣播/多播功能,如果這就是你要求的。 – Dolda2000