簡體   English   中英

使用UNIX流套接字的IPC

[英]IPC using UNIX stream sockets

我有一個波束成形和信號處理系統,其中3個不同的獨立進程可以分別啟動,並且需要每隔幾毫秒相互發送8MB的數據塊。 在這些過程中,我將UNIX流套接字用於IPC。我將塊的接收方作為套接字服務器,將發送方作為客戶端。 每次發送方有要發送的數據時,發送方都會連接到服務器,將數據放在套接字上並斷開連接。 這完美地工作了,但是由於發送方以很高的頻率發送數據,因此我從套接字的“ connect()”函數中收到很多錯誤,如“無此文件或目錄”。 我猜這是因為套接字尚未從上一次傳輸中釋放出來。

客戶端功能:

int sockDAQ, len,respServer;
struct sockaddr_un remote;
int dispConStatus;



        for( j=0;j<16;j++){    

        if ((sockDAQ = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) 
            perror("socket");
        remote.sun_family = AF_UNIX;
        switch(*(daqNum))
        {
            case DAQ1 : strcpy(remote.sun_path, SOCKET_DAQ1_PATH);
                        break;
            case DAQ2 : strcpy(remote.sun_path, SOCKET_DAQ2_PATH);
                        break;
            case DAQ3 : strcpy(remote.sun_path, SOCKET_DAQ3_PATH);
                        break;
            case DAQ4 : strcpy(remote.sun_path, SOCKET_DAQ4_PATH);
                        break;
            case DAQ5 : strcpy(remote.sun_path, SOCKET_DAQ5_PATH);
                        break;
            case DAQ6 : strcpy(remote.sun_path, SOCKET_DAQ6_PATH);
                        break;
            case DAQ7 : strcpy(remote.sun_path, SOCKET_DAQ7_PATH);
                        break;
            case DAQ8 : strcpy(remote.sun_path, SOCKET_DAQ8_PATH);
                        break;

        } 

len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
dispConStatus = connect(sockDAQ, (struct sockaddr *)&remote, len);
        if ( dispConStatus != -1) {
            //printf("beamformer process found by %d.. Transferring packet\n",*(daqNum));     
            //printf("j : %d\n", j);
            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");
            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            }
        else
            printf("FAILED TO FIND BF FOR DAQ %d\n",*(daqNum));

        }

如果嘗試類似的操作,則連接一次服務器,然后繼續發送數據包,由於“ connect()”函數每次都返回-1,因此它似乎在第一次傳輸后不起作用。

更新功能:

int sockDAQ, len,respServer;
struct sockaddr_un remote;
int dispConStatus;

if ((sockDAQ = socket(AF_UNIX,SOCK_STREAM, 0)) == -1) 
            perror("socket");
remote.sun_family = AF_UNIX;
        switch(*(daqNum))
        {
            case DAQ1 : strcpy(remote.sun_path, SOCKET_DAQ1_PATH);
                        break;
            case DAQ2 : strcpy(remote.sun_path, SOCKET_DAQ2_PATH);
                        break;
            case DAQ3 : strcpy(remote.sun_path, SOCKET_DAQ3_PATH);
                        break;
            case DAQ4 : strcpy(remote.sun_path, SOCKET_DAQ4_PATH);
                        break;
            case DAQ5 : strcpy(remote.sun_path, SOCKET_DAQ5_PATH);
                        break;
            case DAQ6 : strcpy(remote.sun_path, SOCKET_DAQ6_PATH);
                        break;
            case DAQ7 : strcpy(remote.sun_path, SOCKET_DAQ7_PATH);
                        break;
            case DAQ8 : strcpy(remote.sun_path, SOCKET_DAQ8_PATH);
                        break;

        } 

len = strlen(remote.sun_path) + sizeof(remote.sun_family);    
dispConStatus = connect(sockDAQ, (struct sockaddr *)&remote, len);



        if ( dispConStatus != -1) {

            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");

            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            usleep(5000);

            respServer = NOT_TERMINATE;
            if ((send(sockDAQ, &respServer, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, &transfer_bytes, sizeof(int), 0))==-1) perror("send");
            if ((send(sockDAQ, buf_1, transfer_bytes, 0))==-1) perror("send");

            pthread_mutex_lock(&bfmutex);
            printf("PACKETS TRANSFERRED %d FROM DAQ %d\n",++sentCount,*(daqNum));
            pthread_mutex_unlock(&bfmutex);

            }

        close(sockDAQ);

這將在send()函數上返回錯誤:

../sysdeps/unix/sysv/linux/x86_64/send.c: No such file or directory.

我的問題是:

  1. 我是否需要在每次需要向套接字發送數據包時終止連接並重新連接。

  2. 有沒有一種方法可以無限期地維護套接字連接,因為持續的連接和重新連接會導致系統中的大量延遲,並且我正在通過套接字丟棄數據包。

  3. 關於connect()函數返回“無此文件或目錄”錯誤,我是否可以假設發生這種情況,是因為內核在創建新連接之前沒有從上次連接中釋放套接字,還是我錯過了一些東西。

幫助將不勝感激。 謝謝。

  1. 不,您不需要關閉插槽,可以保持打開狀態。 請注意,這可能會大大改變服務器的邏輯。 您將需要維護一個套接字池,其中包括每個客戶端的偵聽套接字和一個套接字。 然后您有兩種架構選擇:

    • 每個套接字運行一個線程。

    • 或者,您在套接字池上運行selectpoll來決定下一步。 libev之類的庫可能會使您的生活更輕松。 查看以下示例

  2. 是。 僅在客戶端啟動時connect ,而僅在客戶端退出時呼叫close

  3. 我認為發生此錯誤是因為您需要保持accept -ing連接。 根據您對服務器進行編程的方式,它可能會忙於處理其他客戶端,而不是接受新的連接。 查看此示例,其中顯示了如何接受多個連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM