簡體   English   中英

C unix域套接字,recvfrom()不設置struct sockaddr * src_addr

[英]C unix domain sockets, recvfrom() doesn't set struct sockaddr* src_addr

我正在編寫一個通過unix域套接字偵聽UDP數據包的應用程序。 請考慮以下代碼塊。

int sockfd;
struct sockaddr_un servaddr;

sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);

if(sockfd < 0)
{
    perror("socket() failed");
}

unlink(port);

bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path, port);    

if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
    perror("bind() failed");
    close(sockfd);
}

int n;
struct sockaddr_un cliaddr;
socklen_t len = sizeof(cliaddr);
discovery_msgs client_message;


bzero(&client_message, sizeof(client_message));
// Wait for a message to be received
n = recvfrom(sock_fd, &client_message, sizeof(client_message), 0, 
    (struct sockaddr *) &cliaddr, &len);

// At this point n = 560, client_message is filled with the expected data 
//len = 0 and cliaddr has no information about the client that sent the data

現在client_message的類型並不重要,我收到一個UDP數據包, client_message包含我期望的所有數據。 當我在調用recvfrom后查看cliaddrlen時,問題就出現了。 cliaddr不會被recvfrom修改,就像通常使用普通網絡TCP / UDP一樣,並且len在調用后設置為0(這意味着recvfrom沒有將數據寫入&cliaddr )。 我需要使用unix域路徑填充cliaddr的信息,以便我可以發送響應。

我究竟做錯了什么?

當使用Unix域套接字時,解決方案是綁定客戶端上的套接字。 否則,在sendto() ,為發送UDP數據包而創建的瞬態路徑名會立即消失,這就解釋了為什么客戶端的地址信息在服務器端不可用。

請參閱Stevens Network Programming第419頁或查看此示例以獲取解決此問題的示例客戶端實現:libpix.org/unp/unixdgcli01_8c_source.html

#include    "unp.h"

int
main(int argc, char **argv)
{
    int                 sockfd;
    struct sockaddr_un  cliaddr, servaddr;

    sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);

    bzero(&cliaddr, sizeof(cliaddr));       /* bind an address for us */
    cliaddr.sun_family = AF_LOCAL;
    strcpy(cliaddr.sun_path, tmpnam(NULL));

    Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));

    bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */
    servaddr.sun_family = AF_LOCAL;
    strcpy(servaddr.sun_path, UNIXDG_PATH);

    dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));

    exit(0);
}

注意: unp.h定義了Bind() ,它只是bind()和一些錯誤檢查(在整個史蒂文斯網絡編程中常用)。 以相同的方式, (SA *)等同於(struct sockaddr *)

暫無
暫無

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

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