printf("Connecting to server %s:%d...\n", SERVER_IP, SERVER_PORT); if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { perror("connect failed"); close(sock); exit(EXIT_FAILURE); } printf("Connected to server successfully.\n");
// --- 关键: 使用 getpeername 获取服务器地址 --- printf("\n--- Getting peer (server) name with getpeername ---\n"); // 重新初始化长度,以防被修改 peer_addr_len = sizeof(peer_addr); if (getpeername(sock, (struct sockaddr *)&peer_addr, &peer_addr_len) == 0) { printf("Connected to server at:\n"); printf(" Peer IP Address: %s\n", inet_ntoa(peer_addr.sin_addr)); printf(" Peer Port: %d\n", ntohs(peer_addr.sin_port)); } else { perror("getpeername failed"); // 常见错误:ENOTCONN (如果套接字未连接) }
// (对比) 使用 getsockname 获取自己的本地地址 struct sockaddr_in local_addr; socklen_t local_addr_len = sizeof(local_addr); if (getsockname(sock, (struct sockaddr *)&local_addr, &local_addr_len) == 0) { printf("\nMy local address is:\n"); printf(" Local IP Address: %s\n", inet_ntoa(local_addr.sin_addr)); printf(" Local Port: %d\n", ntohs(local_addr.sin_port)); } else { perror("getsockname failed"); }
printf("\nClient is connected and verified peer/local addresses.\n");
getpmsg 是 System V STREAMS 接口中的函数,用于从 STREAMS 设备接收带优先级的消息。该函数允许按优先级(band)接收消息,支持多种接收模式(MSG_HIPRI/MSG_ANY/MSG_BAND)。参数包括文件描述符、控制/数据缓冲区结构(strbuf)以及优先级/标志指针。函数返回0表示成功,-1表示失败并设置errno。示例代码展示了基础用法和模拟实现,但需注意Linux系统对STREAMS的支持有限。关联函数包括putpmsg、getmsg等,常用于消息优先级处理场景。
函数原型
1 2 3 4 5
#include <stropts.h>
int getpmsg(int fildes, struct strbuf *ctlptr, struct strbuf *dataptr, int *bandp, int *flagsp);
getresuid 是一个 Linux 系统调用,用于同时获取当前进程的真实用户 ID(Real User ID)、有效用户 ID(Effective User ID)和保存的设置用户 ID(Saved Set-user-ID)。这三个 ID 构成了 Unix/Linux 系统中完整的用户身份管理体系。
2. 函数原型
1 2 3 4 5
#include <unistd.h> #include <sys/types.h>
int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
getresgid - 获取进程的真实、有效和保存的组ID
1. 函数介绍
getresgid 是一个 Linux 系统调用,用于同时获取当前进程的真实组 ID(Real Group ID)、有效组 ID(Effective Group ID)和保存的设置组 ID(Saved Set-group-ID)。
2. 函数原型
1 2 3 4 5
#include <unistd.h> #include <sys/types.h>
int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
3. 功能对比
函数功能参数getresuid(ruid, euid, suid)获取用户 ID 三元组3个 uid_t* 指针getresgid(rgid, egid, sgid)获取组 ID 三元组3个 gid_t* 指针
// 模拟一个消耗 CPU 的函数 void cpu_intensive_task() { volatile unsigned long sum = 0; for (unsigned long i = 0; i < 1000000000UL; ++i) { sum += i; } // 使用 sum 防止编译器优化掉循环 if (sum % 2 == 0) { // do nothing } }
int main() { struct itimerval timer;
if (signal(SIGVTALRM, vt_alarm_handler) == SIG_ERR) { perror("signal SIGVTALRM"); exit(EXIT_FAILURE); }
printf("Waiting for 1-second timer to expire...\n"); pause(); // 等待 1 秒计时器超时
// 4. 恢复旧的计时器设置 printf("\nRestoring old timer setting.\n"); if (setitimer(ITIMER_REAL, &old_timer, NULL) == -1) { perror("setitimer restore"); exit(EXIT_FAILURE); }
if (getitimer(ITIMER_REAL, &new_timer) == -1) { perror("getitimer after restore"); exit(EXIT_FAILURE); } print_timer("Timer status after restore", &new_timer);
printf("Waiting for restored timer to expire...\n"); pause(); // 等待恢复的计时器超时
printf("Restored timer expired. Program finished.\n"); return 0; }