strcpy(), memcpy(), Write(), Read().

本文介绍了C语言中常用的字符串操作函数strcpy和memcpy的工作原理,以及CFile类的Write和Read成员函数如何进行文件的数据读写操作。这些函数在软件开发中被广泛使用。

strcpy(char *dest, char *src)  从src 复制到dest, 复制的字符串以'/0'结束

memcpy(char *dest, char *src, int nCount) 从src复制nCount个bytes的内容到dest

CFile类的Write(const void* lpBuf, UINT nCount), Read(void* lpBuf, UINT nCount)都是读或写最多nCount个bytes的内容到文件

将以下程序改为收发均在不同线程内,每隔一秒发送一次数据: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <net/if.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <linux/can.h> #include <linux/can/raw.h> // 初始化CAN套接字 int init_can_socket(const char *interface_name) { int s; struct sockaddr_can addr; struct ifreq ifr; // 创建CAN套接字 if ((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) { perror("socket"); return -1; } // 指定CAN接口 strcpy(ifr.ifr_name, interface_name); ioctl(s, SIOCGIFINDEX, &ifr); addr.can_family = AF_CAN; addr.can_ifindex = ifr.ifr_ifindex; // 绑定套接字到CAN接口 if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) { perror("bind"); close(s); return -1; } return s; } // 发送CAN数据 void send_can_data(int s, canid_t can_id, const uint8_t *data, size_t data_len) { struct can_frame frame; frame.can_id = can_id; frame.can_dlc = data_len; memcpy(frame.data, data, data_len); if (write(s, &frame, sizeof(struct can_frame)) != sizeof(struct can_frame)) { perror("write"); } } // 接收CAN数据并打印 void receive_can_data(int s) { struct can_frame frame; ssize_t nbytes; nbytes = read(s, &frame, sizeof(struct can_frame)); if (nbytes > 0) { printf("[%03X] - ", frame.can_id); for (int i = 0; i < frame.can_dlc; i++) { printf("%02X ", frame.data[i]); } printf("\n"); } } int main() { int s; const char *interface_name = "can0"; canid_t can_id = 0x701; uint8_t data[] = {0x01, 0x02, 0x03, 0x04}; size_t data_len = sizeof(data); // 初始化CAN套接字 s = init_can_socket(interface_name); if (s < 0) { return 1; } // 发送CAN数据 send_can_data(s, can_id, data, data_len); // 循环接收CAN数据 while (1) { receive_can_data(s); } close(s); return 0; }
最新发布
11-29
#include "arp_scanner.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <net/if.h> #include <sys/ioctl.h> #include <linux/if_packet.h> #include <time.h> #include <errno.h> #include "json_api.h" // 从二进制文件加载配置 int load_config(arp_config_t *config) { if (config == NULL) { fprintf(stderr, "错误: 配置指针为空\n"); return -1; } // 使用ds_read读取配置 ds_read(ARPD_CONFIG_PATH, config, sizeof(arp_config_t)); return 0; } S32 arp_scanner_init() { memset(&g_scanner, 0, sizeof(arp_scanner_t)); // 创建原始套接字 g_scanner.raw_socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP)); if (g_scanner.raw_socket < 0) { perror("socket"); return -1; } // 初始化互斥锁 if (pthread_mutex_init(&g_scanner.lock, NULL) != 0) { close(&g_scanner.raw_socket); return -1; } // 从配置文件加载配置 if (load_config(&g_scanner.config) != 0) { // 加载失败时使用默认值 gscanner.config.enabled = FALSE; gscanner.config.scan_interval = 60; gscanner.config.validity_period = 300; gscanner.config.packet_interval = 100; gscanner.config.start_ip = ip_to_int("192.168.1.100"); gscanner.config.end_ip = ip_to_int("192.168.1.200"); // 默认网络接口 strcpy(gscanner.config.interface, "eth0"); fprintf(stderr, "Using default configuration\n"); } return 0; } S32 arp_scanner_start(void) { pthread_mutex_lock(&g_scanner.lock); g_scanner.scanning = TRUE; g_scanner.stop_requested = FALSE; pthread_mutex_unlock(&g_scanner.lock); // 创建扫描线程 pthread_t scan_thread; if (pthread_create(&scan_thread, NULL, scan_thread_func, NULL) != 0) { perror("pthread_create"); return -1; } return 0; } int arp_scanner_stop(arp_scanner_t *scanner) { if (!scanner) return -1; pthread_mutex_lock(&scanner->lock); scanner->stop_requested = TRUE; pthread_mutex_unlock(&scanner->lock); return 0; } int arp_scanner_cleanup(arp_scanner_t *scanner) { if (!scanner) return -1; arp_scanner_stop(scanner); if (scanner->raw_socket >= 0) { close(scanner->raw_socket); } pthread_mutex_destroy(&scanner->lock); return 0; } void *scan_thread_func(void *arg) { arp_scanner_t *scanner = (arp_scanner_t *)arg; while (!scanner->stop_requested) { arp_scanner_scan(scanner); // 等待扫描间隔 sleep(scanner->config.scan_interval); } pthread_mutex_lock(&scanner->lock); scanner->scanning = FALSE; pthread_mutex_unlock(&scanner->lock); return NULL; } int arp_scanner_scan(arp_scanner_t *scanner) { if (!scanner || !scanner->config.enabled) return -1; struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口索引 if (ioctl(scanner->raw_socket, SIOCGIFINDEX, &ifr) < 0) { perror("ioctl"); return -1; } // 绑定到接口 struct sockaddr_ll saddr; memset(&saddr, 0, sizeof(saddr)); saddr.sll_family = AF_PACKET; saddr.sll_ifindex = ifr.ifr_ifindex; saddr.sll_protocol = htons(ETH_P_ARP); if (bind(scanner->raw_socket, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { perror("bind"); return -1; } // 发送ARP请求 for (uint32_t ip = scanner->config.start_ip; ip <= scanner->config.end_ip && !scanner->stop_requested; ip++) { arp_scanner_send_arp_request(scanner, ip); usleep(scanner->config.packet_interval * 1000); } // 处理ARP回复 arp_scanner_process_reply(scanner); // 清理过期条目 arp_scanner_clean_old_entries(scanner); scanner->last_scan_time = time(NULL); return 0; } int arp_scanner_send_arp_request(arp_scanner_t *scanner, uint32_t target_ip) { struct ifreq ifr; strcpy(ifr.ifr_name, scanner->config.interface); // 获取接口MAC地址 if (ioctl(scanner->raw_socket, SIOCGIFHWADDR, &ifr) < 0) { perror("ioctl"); return -1; } unsigned char *src_mac = (unsigned char *)ifr.ifr_hwaddr.sa_data; // 获取接口IP地址 if (ioctl(scanner->raw_socket, SIOCGIFADDR, &ifr) < 0) { perror("ioctl"); return -1; } struct sockaddr_in *ipaddr = (struct sockaddr_in *)&ifr.ifr_addr; uint32_t src_ip = ipaddr->sin_addr.s_addr; // 构建ARP请求包 arp_packet_t packet; // 以太网头部 memset(packet.eth_header.h_dest, 0xFF, 6); // 广播地址 memcpy(packet.eth_header.h_source, src_mac, 6); packet.eth_header.h_proto = htons(ETH_P_ARP); // ARP头部 packet.arp_header.ar_hrd = htons(ARPHRD_ETHER); packet.arp_header.ar_pro = htons(ETH_P_IP); packet.arp_header.ar_hln = 6; packet.arp_header.ar_pln = 4; packet.arp_header.ar_op = htons(ARPOP_REQUEST); memcpy(packet.sender_mac, src_mac, 6); memcpy(packet.sender_ip, &src_ip, 4); memset(packet.target_mac, 0, 6); memcpy(packet.target_ip, &target_ip, 4); // 发送包 struct sockaddr_ll dest; memset(&dest, 0, sizeof(dest)); dest.sll_family = AF_PACKET; dest.sll_ifindex = ifr.ifr_ifindex; dest.sll_halen = ETH_ALEN; memset(dest.sll_addr, 0xFF, ETH_ALEN); ssize_t sent = sendto(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&dest, sizeof(dest)); return (sent == sizeof(packet)) ? 0 : -1; } int arp_scanner_process_reply(arp_scanner_t *scanner) { if (!scanner) { return -1; } fd_set readfds; struct timeval tv; int ret; int max_fd = scanner->raw_socket; // 设置超时时间为2秒,用于等待ARP回复 tv.tv_sec = 2; tv.tv_usec = 0; // 循环处理所有可用的ARP回复 while (1) { FD_ZERO(&readfds); FD_SET(scanner->raw_socket, &readfds); ret = select(max_fd + 1, &readfds, NULL, NULL, &tv); if (ret < 0) { if (errno == EINTR) { // 被信号中断,继续等待 continue; } perror("select"); break; } else if (ret == 0) { // 超时,没有更多数据 break; } if (FD_ISSET(scanner->raw_socket, &readfds)) { arp_packet_t packet; struct sockaddr_ll saddr; socklen_t saddr_len = sizeof(saddr); // 接收ARP数据包 ssize_t received = recvfrom(scanner->raw_socket, &packet, sizeof(packet), 0, (struct sockaddr *)&saddr, &saddr_len); if (received < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { continue; } perror("recvfrom"); continue; } // 检查接收到的数据包长度 if (received < (ssize_t)(sizeof(struct ethhdr) + sizeof(struct arphdr))) { // 数据包太短,不是有效的ARP包 continue; } // 验证以太网类型是否为ARP if (ntohs(packet.eth_header.h_proto) != ETH_P_ARP) { continue; } // 验证ARP硬件类型为以太网 if (ntohs(packet.arp_header.ar_hrd) != ARPHRD_ETHER) { continue; } // 验证ARP协议类型为IP if (ntohs(packet.arp_header.ar_pro) != ETH_P_IP) { continue; } // 检查是否是ARP回复 if (ntohs(packet.arp_header.ar_op) == ARPOP_REPLY) { // 提取发送者IPMAC地址 uint32_t sender_ip; memcpy(&sender_ip, packet.sender_ip, 4); char mac_str[MAX_MAC_LEN]; mac_to_string(packet.sender_mac, mac_str); // 检查IP是否在扫描范围内 if (sender_ip >= scanner->config.start_ip && sender_ip <= scanner->config.end_ip) { // 添加到ARP条目表 arp_scanner_add_entry(scanner, sender_ip, mac_str); // 打印调试信息 char ip_str[MAX_IP_LEN]; int_to_ip(sender_ip, ip_str); printf("Received ARP reply from %s [%s]\n", ip_str, mac_str); } } } } return 0; } int arp_scanner_add_entry(arp_scanner_t *scanner, uint32_t ip, const char *mac) { if (!scanner || !mac) { return -1; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int found_index = -1; BOOL is_new_host = FALSE; // 检查是否已存在该IP的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 更新现有条目 strncpy(scanner->entries[found_index].mac, mac, MAX_MAC_LEN - 1); scanner->entries[found_index].mac[MAX_MAC_LEN - 1] = '\0'; scanner->entries[found_index].last_seen = now; } else { // 添加新条目 if (scanner->entry_count < MAX_ARP_ENTRIES) { arp_entry_t *entry = &scanner->entries[scanner->entry_count]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; scanner->entry_count++; is_new_host = TRUE; } else { // ARP表已满,找到最旧的条目替换 time_t oldest_time = now; int oldest_index = 0; for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].last_seen < oldest_time) { oldest_time = scanner->entries[i].last_seen; oldest_index = i; } } // 替换最旧的条目 arp_entry_t *entry = &scanner->entries[oldest_index]; entry->ip = ip; strncpy(entry->mac, mac, MAX_MAC_LEN - 1); entry->mac[MAX_MAC_LEN - 1] = '\0'; entry->last_seen = now; entry->first_seen = now; is_new_host = TRUE; } } pthread_mutex_unlock(&scanner->lock); // 如果是新发现的主机,打印到串口 if (is_new_host) { char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("NEW HOST: IP=%s, MAC=%s\n", ip_str, mac); } return 0; } void arp_scanner_clean_old_entries(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); time_t now = time(NULL); int write_index = 0; for (int read_index = 0; read_index < scanner->entry_count; read_index++) { if (now - scanner->entries[read_index].last_seen <= scanner->config.validity_period) { // 条目未过期,保留 if (write_index != read_index) { scanner->entries[write_index] = scanner->entries[read_index]; } write_index++; } else { // 条目过期,打印日志 char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[read_index].ip, ip_str); printf("EXPIRED: IP=%s, MAC=%s\n", ip_str, scanner->entries[read_index].mac); } } // 更新条目计数 int expired_count = scanner->entry_count - write_index; scanner->entry_count = write_index; pthread_mutex_unlock(&scanner->lock); if (expired_count > 0) { printf("Cleaned %d expired ARP entries\n", expired_count); } } void arp_scanner_print_results(arp_scanner_t *scanner) { if (!scanner) { return; } pthread_mutex_lock(&scanner->lock); printf("\n=== ARP Scan Results ===\n"); printf("Total hosts: %d\n", scanner->entry_count); printf("Last scan: %s", ctime(&scanner->last_scan_time)); printf("-----------------------------------------------\n"); printf("IP Address\t\tMAC Address\t\tFirst Seen\t\tLast Seen\n"); printf("-----------------------------------------------\n"); for (int i = 0; i < scanner->entry_count; i++) { char ip_str[MAX_IP_LEN]; int_to_ip(scanner->entries[i].ip, ip_str); char first_seen_str[64]; char last_seen_str[64]; struct tm *tm_info; tm_info = localtime(&scanner->entries[i].first_seen); strftime(first_seen_str, sizeof(first_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); tm_info = localtime(&scanner->entries[i].last_seen); strftime(last_seen_str, sizeof(last_seen_str), "%Y-%m-%d %H:%M:%S", tm_info); printf("%-15s\t%s\t%s\t%s\n", ip_str, scanner->entries[i].mac, first_seen_str, last_seen_str); } printf("-----------------------------------------------\n"); pthread_mutex_unlock(&scanner->lock); } int arp_scanner_remove_entry(arp_scanner_t *scanner, uint32_t ip) { if (!scanner) { return -1; } pthread_mutex_lock(&scanner->lock); int found_index = -1; // 查找要删除的条目 for (int i = 0; i < scanner->entry_count; i++) { if (scanner->entries[i].ip == ip) { found_index = i; break; } } if (found_index >= 0) { // 移动后续条目覆盖要删除的条目 for (int i = found_index; i < scanner->entry_count - 1; i++) { scanner->entries[i] = scanner->entries[i + 1]; } scanner->entry_count--; char ip_str[MAX_IP_LEN]; int_to_ip(ip, ip_str); printf("Removed ARP entry: %s\n", ip_str); } pthread_mutex_unlock(&scanner->lock); return (found_index >= 0) ? 0 : -1; } // 工具函数 uint32_t ip_to_int(const char *ip) { if (!ip) { return 0; } struct in_addr addr; if (inet_pton(AF_INET, ip, &addr) != 1) { fprintf(stderr, "Invalid IP address: %s\n", ip); return 0; } return addr.s_addr; } void int_to_ip(uint32_t ip_int, char *ip_str) { if (!ip_str) { return; } struct in_addr addr; addr.s_addr = ip_int; inet_ntop(AF_INET, &addr, ip_str, MAX_IP_LEN); } void mac_to_string(const unsigned char *mac, char *mac_str) { if (!mac || !mac_str) { return; } snprintf(mac_str, MAX_MAC_LEN, "%02X:%02X:%02X:%02X:%02X:%02X", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); } 把所有函数都统一成全局变量模式,并且整个应用是单线程循环而不是多线程的应用
08-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值