I created a program in C language (server and clients), where the server provides a chat room service to clients who connect to the server. The server allows you to exchange data with cryptographic algorithms and protocols. To store information about clients, I created structures and linked them in two-way link lists. Now I'm working on a case where a client disconnects from the server and I need to delete it from the list and put the new list back together properly.
This is strucute CLIENT:
//Client structure and new data type CLIENT
typedef struct client {
char address_buffer[100];
SOCKET sock_fd;
salt_channel_t channel;
socklen_t client_len;
struct sockaddr_storage client_address;
struct client *p_next;
struct client *p_previous;
} CLIENT;
And this is LIST:
typedef struct {
int count;
CLIENT *p_head;
CLIENT *p_tail;
} LIST;
I added functions to create a list, release a list, create a client, list the whole list, find a specific client in the list, for example by socket, insert a new client etc ... but I still have trouble writing a function that removes a specific user from the list and fills in quite empty the place.
My function for deleting a specific user looks like this:
void realese_client(LIST *p_list,
CLIENT *p_client)
{
CLIENT *p_new_previous;
CLIENT *p_new_next;
//p_list has only one p_client
if ((p_list->p_head->sock_fd == p_client->sock_fd) && (p_list->p_tail->sock_fd == p_client->sock_fd))
{
free(p_list->p_head);
free(p_list->p_tail);
p_list->p_head = NULL;
p_list->p_tail = NULL;
}
//There are some p_client on the p_list but no p_head or p_tail
else if (p_list->p_tail != NULL)
{
p_new_previous = p_client->p_previous;
p_new_next = p_client->p_next;
p_new_previous->p_next = p_new_next;
p_new_next->p_previous = p_new_previous;
free(p_client);
} //p_list has p_client as p_tail
else if (p_list->p_tail->sock_fd == p_client->sock_fd)
{
p_new_previous = p_list->p_tail->p_previous;
p_list->p_tail = p_new_previous;
p_new_previous->p_previous = p_list->p_tail;
free(p_client);
}
else
{ //p_list is empty
printf("List is empty !!!\n");
printf("Unable to delete p_client !!!\n");
}
}
When I call function, the application crashes.
My function for insert client:
//Function for connecting a new node to the list
void insert(LIST *p_list,
CLIENT *p_client)
{
//There are some p_client on the p_list
if (p_list->p_tail != NULL)
{
//Connecting the last person as a new person
p_list->p_tail->p_next = p_client;
//Joining a new person to a former last person
p_client->p_previous = p_list->p_tail;
//Save a new p_tail
p_list->p_tail = p_client;
}
else
{ //p_list is empty
//There is none in front of the p_client
p_client->p_previous = NULL;
//Assigning a p_client to the list (head and tail)
p_list->p_head = p_client;
p_list->p_tail = p_client;
}
p_client->p_next = NULL;
p_list->count ;
}
CodePudding user response:
It seems that the insert function works properly but the delete function logic is kinda blurry personally I would prefer to use recursion approach to handle linked lists I didn't exactly test this snippet but I took it from old code I had written a long time ago and changed it accordingly to match your case i hope this will help
CLIENT * deleteNode(CLIENT * head, SOCKET socket_fd) {
if(head == NULL) return NULL;
if(head->socket_fd == socket_fd ){
CLIENT *pre = head;
head=head->p_next;
head->p_previous=NULL;
free(pre);
return head;
}
head->p_next=deleteNode(head->p_next,socket_fd);
return head;
}
void realese_client(LIST *p_list,CLIENT *p_client){
//check the validity of function arguments first for safety purposes
if(p_list == NULL || p_client == NULL) return;
SOCKET socket_fd=p_client->socket_fd;
ClIENT head=p_list->p_head;
CLIENT tail=p_list->p_tail;
//if list of the client is empty exit
if(tail == NULL) return;
//test if there is one node
if(head == tail){
if(head->socket_fd == socket_fd){
p_list->p_head=NULL;
p_list->p_tail=NULL;
free(head);
}
return;
}
if(tail->socket_fd == socket_fd){
p_list->p_tail=tail->previous;
p_list->p_tail->p_next=NULL;
free(tail);
return;
}
if(head->socket_fd == socket_fd){
p_list->p_head=head->p_next;
p_list->p_head->p_previous=NULL;
free(head);
return;
}
deleteNode(p_list->p_head,p_client->socket_fd);
}