我用 C 語言(服務器和客戶端)創建了一個程式,其中服務器為連接到服務器的客戶端提供聊天室服務。服務器允許您使用加密演算法和協議交換資料。為了存盤有關客戶端的資訊,我創建了結構并將它們鏈接到雙向鏈接串列中。現在我正在處理一個客戶端與服務器斷開連接的情況,我需要從串列中洗掉它并將新串列正確地重新組合在一起。
這是結構化的客戶端:
//客戶端結構和新資料型別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;
這是串列:
typedef struct {
int count;
CLIENT *p_head;
CLIENT *p_tail;
} LIST;
我添加了創建串列、發布串列、創建客戶端、列出整個串列、在串列中查找特定客戶端(例如通過套接字、插入新客戶端等)的函式……但我仍然無法撰寫函式從串列中洗掉特定用戶并填充相當空的地方。
我洗掉特定用戶的函式如下所示:
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");
}
}
當我呼叫函式時,應用程式崩潰。
我的插入客戶端功能:
//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 ;
}
uj5u.com熱心網友回復:
似乎插入函式作業正常,但洗掉函式邏輯個人有點模糊我更喜歡使用遞回方法來處理鏈表我沒有完全測驗這個片段,但我從很久以前寫的舊代碼中獲取了它并相應地更改它以匹配您的情況我希望這會有所幫助
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);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/368148.html
