我一直致力于制作队列并尝试管理它。我需要一个队列来保存我的udp单服务器/多客户端应用程序中的活动客户端记录(我被迫使用udp所以请不要建议转移到tcp)。
有单个服务器和x个客户端。每当客户端发送第一条消息时,该客户端的ip号和端口号就会被推送()到队列中。
然后,每隔5秒,服务器pop()s ip和端口号从队列中出来,并使用此ip和端口号向客户端发送消息。如果客户在特定时间内回复,则会被视为“有效”,但如果在超时内没有收到客户的回复,则客户端被视为已死,必须从队列中删除。
现在的问题是如何删除此节点。一个选项是简单地添加NULL代替此节点,但我想从队列中完全删除此节点。
任何建议都非常受欢迎。
以下是我的代码:
struct node
{
int rollno;
struct node*n;
};
struct node* create()
{
struct node*q;
q=(struct node*)malloc(sizeof(struct node));
return q;
}
void push(struct node*cur)
{
if(head==NULL)
{
head = cur;
tail = cur;
start = cur; //keeps a track of first node
}
else
{
struct node*f;
f=head;
head->n = cur;
head=head->n; //keep updating head
}
}
struct node* pop()
{
struct node*p;
struct node*s = NULL;p = tail;
if (p == head && tail != head) /*if at the end of list, display starting from first element as Queue is FIFO*/
{
p = start;
tail=p->n;
s = p;
display(s);
return s;
}
if(p == NULL)
{
if (start == NULL) //if no emelemt yet in the Queue
return NULL;
else // if at the End of list, go back to start
{
p = start;
tail=p->n;
s = p;
}
}
else
{
tail=p->n; //keep updating tail
s = p;
}
display(s);
return s;
}
void main()
{
while(1)
{
//if new client
struct node*j;
j = create();
// j= ip and port of client.
j->n=NULL;
push(j);
//after every 5 secs
{
pop();
//if client fails to reply
{
delete node.
}
}
}
}
答案 0 :(得分:1)
由于它意味着是一个队列,删除只会发生在前面,这意味着你只需要摆脱头部元素。类似的东西:
void delete()
{
node* temp = head; /* store the head the pointer so we can free it later */
head = head->next; /* make the node next to head be the head */
free(temp); /* free the original head pointer */
}
考虑到您的评论,如果我已正确理解您需要删除链接列表中的任何节点。
这是链接列表中节点的删除功能,它处理三个独立的案例 - 如果要删除的节点是头部,是尾部还是中间(请注意,您需要提供自己的功能来识别死节点:
/* need id argument to know which node needs to be deleted
* we need to already know which node is dead */
void delete_arbitrary(int id)
{
if (head->rollno == id) /* id matches that of head, let's delete it */
{
node* temp = head; /* store the head pointer so we can free it later */
head = head->next; /* make the node next to head be the head */
free(temp); /* free the original head pointer */
}
else /* node somewhere down the line, let's find it */
{
node* curr = head->next /* start from the node after the head */
node* prev; /* this is to keep track of the previous node */
while(curr->rollno != id && curr != NULL)
{
prev = curr;
curr = curr->next;
}
if (curr == NULL) /* didn't find it so let's report it and quit */
{
printf("Node not found\n");
}
else if (curr->next == NULL) /* we're at the tail */
{
node* temp = tail; /* store it for later deletion */
tail = prev; /* the previous node is now the tail */
free(temp); /* free the old tail */
}
else /* it's somewhere in between */
{
prev->next = curr->next; /* the previous node now points to the one after the current */
free(curr); /* get rid of the current pointer */
}
}
}
答案 1 :(得分:1)
如果您使用 malloc 功能为节点分配内存,则可以使用 free 功能释放该内存。这里你没有为j指针分配内存,这是一个错误。
在您的应用程序中,您必须每5分钟检查一个元素是否处于活动状态,如果此时任何节点处于非活动状态,您必须将其删除。所以,我认为你不需要FIFO数据结构。最好使用链表数据结构。
答案 2 :(得分:1)
正如DPG所说,链表更适合这里。
现在,你需要这样的东西吗?
void freenode(struct node* n)
{
struct node* p = start;
struct node* last = start;
while (p != NULL) {
if (p == n) {
if (p == start) {
if (p->n = NULL) {
head = NULL;
start = NULL;
tail = NULL;
}
else {
if (tail == start)
tail = start->n;
start = start->n;
}
}
else if (p == head) {
head = last;
head->n = NULL;
}
else {
last->n = p->n;
}
free(p);
break;
}
last = p;
p = p->n;
}
}