gpt4 book ai didi

c - 线程中的链表?

转载 作者:太空宇宙 更新时间:2023-11-04 03:27:51 25 4
gpt4 key购买 nike

我编写了一个 C 脚本,我试图在其中接收 NTP 数据包并将它们添加到一个链表中,该链表然后根据每个 IP 接收到的 NTP 数据包的数量对其进行排序。

使用checkInList() 命令似乎在main() 中的测试中工作正常,但在recievethread() 中调用时比较错误的ip

预期输出:

[ (187.1.160.84:31) (255.255.255.255:400) (8.8.8.8:0) (192.168.2.1:0)  ]

这意味着我们从 255.255.255.255 0 从 8.8.8.8 等收到了 400 个数据包。

实际输出:

[ (187.1.160.84:431) ]

发生的情况是数据包计数不断增加,但 ip 只是更改为最新的而不是添加新的。

代码:

struct node  
{
char *ip;
int count;
struct node *next;
};

struct node *head = NULL;
struct node *current = NULL;

void printInList()
{
struct node *ptr = head;
printf("\n[ ");

//start from the beginning
while(ptr != NULL)
{
printf("(%s:%d) ", ptr->ip, ptr->count);
ptr = ptr->next;
}

printf(" ]");
}


int length()
{
int length = 0;
struct node *current;

for(current = head; current != NULL; current = current->next)
{
length++;
}

return length;
}
void sort(){

int i, j, k, tempKey, tempData ;
struct node *current;
struct node *next;

int size = length();
k = size ;

for ( i = 0 ; i < size - 1 ; i++, k-- ) {
current = head ;
next = head->next ;

for ( j = 1 ; j < k ; j++ ) {

if ( current->count < next->count ) {
tempData = current->count ;
current->count = next->count;
next->count = tempData ;

tempKey = current->ip;
current->ip = next->ip;
next->ip = tempKey;
}

current = current->next;
next = next->next;
}
}
}

void insertInList(char *ipaddr, int count)
{
#ifdef DEBUG
printf("Inserting: %s:%d\t", ipaddr, count);
#endif
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));

link->ip = ipaddr;
link->count = count;
#ifdef DEBUG
printf("Inserted: %s:%d\t", link->ip, link->count);
#endif
//point it to old first node
link->next = head;

//point first to new first node
head = link;
}

int checkInList(const char *string)
{
/*
If 1 returned means we found it
If 0 Means we didnt find it
*/
struct node *ptr = head;

//start from the beginning
while(ptr != NULL)
{
#ifdef DEBUG
printf("Comparing %s and %-20s", ptr->ip, string);
#endif
if(strcmp(ptr->ip, string) == 0) {
#ifdef DEBUG
printf("Adding count: %s->%d\n", ptr->ip, ptr->count);
#endif
ptr->count++;
return 0;
}
ptr = ptr->next;
}
#ifdef DEBUG
printf("Returning 1\n");
#endif
return 1;
}

void *recievethread()
{
int saddr_size, data_size, sock_raw;
struct sockaddr_in saddr;
struct in_addr in;

unsigned char *buffer = (unsigned char *)malloc(65536);
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
if(sock_raw < 0)
{
printf("Socket Error\n");
exit(1);
}
while(1) {
saddr_size = sizeof saddr;
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , (struct sockaddr *)&saddr , &saddr_size);
if(data_size < 0) {
printf("Recvfrom error , failed to get packets\n");
exit(1);
}
struct iphdr *iph = (struct iphdr*)buffer;
if(iph->protocol == 17)
{
unsigned short iphdrlen = iph->ihl*4;
struct udphdr *udph = (struct udphdr*)(buffer + iphdrlen);
unsigned char* payload = buffer + iphdrlen + 8;
if(ntohs(udph->source) == 123) {
int body_length = data_size - iphdrlen - 8;
if (body_length > 47) {
if(checkInList(inet_ntoa(saddr.sin_addr)) == 1) {
insertInList(inet_ntoa(saddr.sin_addr), 0);
}
}
}
}
}
close(sock_raw);
}

int main()
{
pthread_t listenthread;
pthread_create( &listenthread, NULL, &recievethread, NULL);

// Some tests
if(checkInList("192.168.2.1") == 1) {
insertInList("192.168.2.1", 0);
}
if(checkInList("8.8.8.8") == 1) {
insertInList("8.8.8.8", 0);
}

while(1) {
sort();
printInList();
sleep(1);
}
printf("\n");
return 0;
}

抱歉,如果它没有意义,如果您认为它对我有帮助,请随时将我重定向到另一个线程。

最佳答案

正如其他人所指出的,您需要锁定列表以使其正确。

但是,问题的最直接原因是 inet_ntoa() 返回一个指向静态分配缓冲区的指针,该缓冲区在下一次调用时被覆盖。您正在链表中记录指向此缓冲区的指针,因此当您下次调用 inet_ntoa() 时,链表节点指向的字符串会发生变化。

插入节点时需要复制字符串:

link->ip = strdup(ipaddr);

锁定的一种简单方法是创建全局 pthread_mutex_t:

pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;

然后将其锁定在列表检查/插入周围:

pthread_mutex_lock(&list_lock);
if (checkInList(inet_ntoa(saddr.sin_addr)) == 1) {
insertInList(inet_ntoa(saddr.sin_addr), 0);
}
pthread_mutex_unlock(&list_lock);

围绕排序/打印:

pthread_mutex_lock(&list_lock);
sort();
printInList();
pthread_mutex_unlock(&list_lock);

关于c - 线程中的链表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39815094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com