我试图使用 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;
}
在这里,我遇到了段错误。考虑了一下,我明白“下一个”指针指向服务器程序地址空间中的一个地址,因此客户端可以访问它。所以我使用了一个字符串数组来传递 d_name 列表,很明显,它工作得很好。
所以,我的问题是:
<强>1。有什么方法可以通过套接字连接传递链表吗?
<强>2。如果不是,那么通过网络传递组成文件和目录列表的最佳方法是什么?在真正的NFS中是如何实现的?
最佳答案
- Is there any way of passing a linked list over a socket connection?
不直接,不。您需要做的是通过套接字连接发送一些字节,以某种定义明确的格式发送,接收程序可以使用这些格式来构建相同的链表。
正如其他人在评论中指出的那样,通过套接字连接发送指针是没有用的,因为指针仅在发送进程的内存空间内有效——即使您确实发送了指针的值,它也不会t 是接收器内存空间中的有效指针。
幸运的是不需要发送指针;相反,只需发送有效负载数据(在您的情况下为 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;
}
... 然后接收方将运行类似以下的代码(同样,伪代码;真实代码将进行适当的错误检查等):
// 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)
关于c - 通过套接字传递链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55233747/