2014-09-05 61 views
1

我有用C和Python编写的发送者/接收者对代码。客户端正在生成数据并通过unix套接字将其发送给接收方。 Receiver并不总是在监听套接字,因为它应该对接收到的数据进行处理。没有发送(或接收)队列的Unix套接字

在我当前的代码中,发件人发送的所有邮件都在队列中等待被接收者接收,但我不想要这种行为。我希望发件人知道接收器现在很忙(甚至可能引发错误)。那么如何将接收器的队列长度设置为零?

请考虑我不希望发送或接收程序被阻止。代码

我的接收器和发送器部分是这些:

接收器(在Python):

self.app_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM) 
self.app_socket.settimeout(0.01) 
self.app_socket.bind(APP_SOCKET) 

def poll(self, *args): 
    try: 
     message = self.app_socket.recv(1024) 
    except socket.timeout: 
     return 

发件人(C语言):

int openSocket(char *path) 
{ 
    int sock; 
    struct sockaddr_un addr; 
    int size; 

    sock = socket(AF_UNIX, SOCK_DGRAM, 0); 
    if (sock < 0) 
     exit (EXIT_FAILURE); 

    addr.sun_family = AF_UNIX; 
    strcpy(addr.sun_path, path); 
    size = strlen(addr.sun_path) + sizeof(addr.sun_family); 

    if (connect(sock, (struct sockaddr *) &addr, size) < 0) 
     return -1; 

    return sock; 
} 

int sendMessage(int sock, unsigned char *message, int length) 
{ 
    int count; 

    count = send(sock, message, length, 0); 
    if (count < 0) 
     return -1; 

    return count; 
} 
+0

我请你怎么看'人3选择'工作,我认为它可以帮助你知道接收器的状态 – CollioTV 2014-09-05 09:41:06

+0

@CollioTV谢谢,我知道'select',但我认为这是一个非常普遍的答案。顺便说一句,我正在读这个。 – MostafaR 2014-09-05 10:20:17

+1

'select()'只会告诉你send()是否可以在没有阻塞的情况下工作,发送的数据最终在OS缓冲区中等待是'select()'告诉你它之后的有效(可能)确定'send()' – 2014-09-05 16:02:27

回答

3

你不能告诉上发件人方接收方正在发生什么。可能是接收过程现在甚至没有预定。唯一合理的方法是从接收者回答发件人,在那里你可以等待这个答案超时,并决定接收者是否忙。

+0

非常感谢您的回答,如果我想让它更容易,对于我来说,如果消息不在队列中等待就足够了,我的意思是可以在接收器代码中打开一个套接字没有任何队列?如果我在接收器繁忙时丢失消息,对我来说没问题。 – MostafaR 2014-09-05 16:38:15

+1

简而言之 - 不,你不能。通常,当你发送()一些数据时,你要求内核把你的消息发送到另一个套接字。在那个时刻(假设你有1个CPU,为了清晰起见)你的接收器处理器不工作,它正在等待内核调度。内核有存储你的消息的地方,你的接收器可以在什么时候得到它,当它的proc将被安排。 – 2014-09-05 19:01:57

2

您需要某种方式让接收者将其状态(读取或不读取)发送给发件人。 有几个IPC原语可用于此目的。

或者你可以自己做。 例如,接收器可以使沿着这些线路的东西:

mkdir("/path/to/my/flag/dir", 0555); /* ready */ 
    read(); 
    rmdir("/path/to/my/flag/dir");  /* busy */ 

和发送者可以定期的东西沿着这些线路检查的这种存在:

oktogo = (access("/path/to/my/flag/dir", F_OK) == 0); 
相关问题