linux recvmsg,Linux:可以使用Recvmsg接收每个传入数据包的IP_TOS

本文分享了解决问题的代码,介绍了在Linux下设置UDP Socket接收IP_TTL和IP_TOS值的方法。包括设置套接字以接收对应值,从每个数据包中检索这些值,以及发送和获取数据消息的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我终于设法解决了这个问题,并在这里添加了代码供其他人使用.我希望这对别人有帮助.这个是IP_TTL:

设置UDPSocket以接收IP_TTL值:

int ttl = 60;

if(setsockopt(udpSocket, IPPROTO_IP, IP_RECVTTL, &ttl,sizeof(ttl))<0)

{

printf("cannot set recvttl\n");

}

else

{

printf("socket set to recvttl\n");

}

并按以下方式从每个数据包中检索IP_TTL值(以下程序可以通过iov [0]检索数据消息,下面给出了代码片段):

struct msghdr msg;

struct iovec iov[1];

memset(&msg, '\0', sizeof(msg));

msg.msg_iov = iov;

msg.msg_iovlen = 1;

iov[0].iov_base = (char *) &pkt;

iov[0].iov_len = sizeof(pkt);

int *ttlptr=NULL;

int received_ttl = 0;

int cmsg_size = sizeof(struct cmsghdr)+sizeof(received_ttl); // NOTE: Size of header + size of data

char buf[CMSG_SPACE(sizeof(received_ttl))];

msg.msg_control = buf; // Assign buffer space for control header + header data/value

msg.msg_controllen = sizeof(buf); //just initializing it

nRet = recvmsg(udpSocket, &msg, 0);

if (nRet > 0) {

struct cmsghdr *cmsg;

for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg,cmsg)) {

if ((cmsg->cmsg_level == IPPROTO_IP) && (cmsg->cmsg_type == IP_TTL) &&

(cmsg->cmsg_len) ){

ttlptr = (int *) CMSG_DATA(cmsg);

received_ttl = *ttlptr;

printf("received_ttl = %i and %d \n", ttlptr, received_ttl);

break;

}

}

}

可以通过以下方式发送和获取数据消息:

发件人方:

struct DATA_to_SEND pkt;

struct msghdr msg;

struct iovec iov[1];

memset(&msg, '\0', sizeof(msg));

msg.msg_iov = iov;

msg.msg_iovlen = 1;

iov[0].iov_base = (char *) &pkt;

iov[0].iov_len = sizeof(pkt);

nRet = sendmsg(udpSocket, &msg,0);

接收方(假设DATA_To_SEND有一个名为“seq”的参数):

struct DATA_to_SEND pkt;

seqNum = ((struct DATA_to_SEND *) iov[0].iov_base)->seq;

以下是IP_TOS.

设置套接字以接收IP_TOS:

unsigned char set = 0x03;

if(setsockopt(udpSocket, IPPROTO_IP, IP_RECVTOS, &set,sizeof(set))<0)

{

printf("cannot set recvtos\n");

}

else

{

printf("socket set to recvtos\n");

并通过以下方式从每个数据包标头中检索IP_TOS值:

struct PC_Pkt pkt;

int *ecnptr;

unsigned char received_ecn;

struct msghdr msg;

struct iovec iov[1];

memset(&msg, '\0', sizeof(msg));

msg.msg_iov = iov;

msg.msg_iovlen = 1;

iov[0].iov_base = (char *) &pkt;

iov[0].iov_len = sizeof(pkt);

int cmsg_size = sizeof(struct cmsghdr)+sizeof(received_ecn);

char buf[CMSG_SPACE(sizeof(received_ecn))];

msg.msg_control = buf;

msg.msg_controllen = sizeof(buf);

nRet = recvmsg(udpSocket, &msg, 0);

if (nRet > 0) {

struct cmsghdr *cmsg;

for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;

cmsg = CMSG_NXTHDR(&msg,cmsg)) {

if ((cmsg->cmsg_level == IPPROTO_IP) &&

(cmsg->cmsg_type == IP_TOS) && (cmsg->cmsg_len) ){

ecnptr = (int *) CMSG_DATA(cmsg);

received_ecn = *ecnptr;

int isecn = ((received_ecn & INET_ECN_MASK) == INET_ECN_CE);

printf("received_ecn = %i and %d, is ECN CE marked = %d \n", ecnptr, received_ecn, isecn);

break;

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值