通过套接字传递链表

3

我试图使用TCP套接字实现一种非常简单的NFS形式。除了"ls"命令之外,所有功能都正常工作。我的计划是使用链表结构传递当前目录中组成文件和目录名称列表。我编写了以下代码:

最初的回答:

                struct lnode
                {
                   char name[256];
                   struct lnode* next;
                };
                DIR* drptr = opendir("."); //as of now, only current directory is considered
                if(drptr==NULL)
                {
                    perror("Could not open");
                }
                else
                {
                    struct dirent* drnt;
                    struct lnode* head = NULL,*tail = NULL;
                    drnt = readdir(drptr);
                    while(drnt!=NULL)
                    {

                        if(strcmp(drnt->d_name,".")!=0&&strcmp(drnt->d_name,"..")!=0)
                        {
                             if(head==NULL)
                             {
                                head = (struct lnode*)malloc(sizeof(struct lnode));
                                strcpy(head->name,drnt->d_name);
                                head->next = NULL;
                                teail = head;
                             }
                             else
                             {
                                tail->next = (struct lnode*)malloc(sizeof(struct lnode));
                                strcpy(tail->next->name,drnt->d_name);
                                tail->next->next = NULL;
                                tail = tail->next;
                             }
                        }
                        else
                        {
                            break;
                        }
                        drnt = readdir(drptr);
                    }
                    write(1,head,sizeof(lnode)); // the socket is duped to 1, so 1 is used for socket communication
                }

在客户端,我是这样读取的:

最初的回答:

struct lnode* l,*q;
recv(sfd,l,sizeof(struct lnode),0);
q = l;
while(q!=NULL)
{
   printf("%s\n",q->name);
   q = q->next;
}

这里我遇到了段错误。经过思考,我了解到“next”指针指向服务器程序地址空间中的地址,因此客户端无法访问它。所以我使用字符串数组传递d_name列表,显然,这个方法完美地解决了问题。
所以,我的问题是:
1. 有没有办法通过套接字连接传递链接列表? 2. 如果不行,那最佳的方法是如何在网络上传递文件和目录列表?在真正的NFS中如何实现?

你需要对列表进行序列化。你不能通过套接字传递指针,它是你内存中的地址。 - Barmar
1
您只是发送了一个节点,而不是整个列表。 - Barmar
为什么不看一下真正的NFS是如何做的呢? - Barmar
1
它使用XDR进行数据表示,您可以使用XDR编码库。 - Barmar
https://en.wikipedia.org/wiki/External_Data_Representation - Barmar
显示剩余2条评论
1个回答

3
没有直接的方法可以通过socket连接传递链表。需通过以某种明确定义的格式向socket连接发送一些字节,以便接收程序可以使用这些字节构建一个完全相同的链表。正如其他人在评论中指出的那样,发送指针跨越socket连接是无用的,因为该指针仅在发送进程的内存空间中有效。即使您传递了指针值,它也不会成为接收器内存空间中的有效指针。幸运的是,没有必要发送指针。相反,只需发送有效载荷数据(在此例中为name数组),并且让接收器在接收到有效载荷数据时创建一个新的链表。例如(伪代码,注意有很多方法可以实现这个过程,这只是我认为比较简单的一种方法):
 // compute the length of the linked list we want to send
 int numNodesInLinkedList = 0;
 struct lnode * n = headNode;
 while(n)
 {
    numNodesInLinkedList++;
    n = n->next;
 }

 // sender:  First, send a string telling the receiver how many nodes to expect
 char headerBuffer[256];
 sprintf(headerBuffer, "%i", numNodesInLinkedList);
 send(sfd, headerBuffer, sizeof(headerBuffer), 0);

 // Then send that many node's worth of name-data
 struct lnode * n = headNode;
 while(n)
 {
    send(sfd, n->name, sizeof(n->name), 0);
    n = n->next;
 }

"最初的回答"翻译成英文是 "Original Answer"。以下是需要翻译的内容:

...然后接收方将运行类似以下代码的代码(再次,伪代码;实际代码将进行适当的错误检查等):

 // receiver:  First, receive the string containing the number-of-nodes-to-receive
 char headerBuffer[256];
 recv(sfd, headerBuffer, sizeof(headerBuffer), MSG_WAITALL);

 const int numNodesInLinkedList = atoi(headerBuffer);
 struct lnode * headNode = NULL;
 struct lnode * tailNode = NULL;

 // Then receive that many names, and place them into our new linked-list
 for (int i=0; i<numNodesInLinkedList; i++)
 {
    struct lnode * newNode = malloc(sizeof(struct lnode));
    newNode->next = NULL;

    recv(sfd, newNode->name, sizeof(newNode->name), MSG_WAITALL);
    if (tailNode)
    {
       tailNode->next = newNode;
       tailNode = newNode;
    }
    else tailNode = headNode = newNode;
 }

 // at this point, headNode points to the start of the received linked-list
 // and tailNode points to the last received node in the list
 // (or both headNode and tailNode are NULL if the list was empty)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接