2014-09-05 83 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); 
相關問題