2017-05-26 29 views
4

报价表这online kernel doc的Linux TCP套接字时间戳选项

  • SO_TIMESTAMPING 生成的接收,传输或两者的时间戳。支持 多个时间戳源,包括硬件。支持生成 时间戳套接字。

Linux支持TCP时间戳,我试图写一些演示代码以获取TCP数据包时间戳。

下面的服务器代码:

//Bind 
if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) 
{ 
    perror("bind failed. Error"); 
    return 1; 
} 
puts("bind done"); 

//Listen 
listen(socket_desc , 3); 

//Accept and incoming connection 
puts("Waiting for incoming connections..."); 
int c = sizeof(struct sockaddr_in); 

client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c); 
if (client_sock < 0) 
{ 
    perror("accept failed"); 
    return 1; 
} 

// Note: I am trying to get software timestamp only here.. 
int oval = SOF_TIMESTAMPING_RX_SOFTWARE | SOF_TIMESTAMPING_SOFTWARE; 
int olen = sizeof(oval); 
if (setsockopt(client_sock, SOL_SOCKET, SO_TIMESTAMPING, &oval, olen) < 0) 
    { perror("setsockopt TIMESTAMP"); exit(1); } 

puts("Connection accepted"); 

char buf[] = "----------------------------------------"; 
int len = strlen(buf); 

struct iovec myiov[1] = { {buf, len } }; 

unsigned char cbuf[ 40 ] = { 0 }; 
int  clen = sizeof(cbuf); 

struct msghdr mymsghdr = { 0 }; 
mymsghdr.msg_name = NULL; 
mymsghdr.msg_namelen = 0; 
mymsghdr.msg_iov = myiov; 
mymsghdr.msg_iovlen = 1; 
mymsghdr.msg_control = cbuf; 
mymsghdr.msg_controllen = clen; 
mymsghdr.msg_flags = 0; 

int read_size = recvmsg(client_sock, &mymsghdr, 0); 

if(read_size == 0) 
{ 
    puts("Client disconnected"); 
    fflush(stdout); 
} 
else if(read_size == -1) 
{ 
    perror("recv failed"); 
} 
else 
{ 
    struct msghdr *msgp = &mymsghdr; 
    printf("msg received: %s \n",(char*)msgp->msg_iov[0].iov_base);// This line is successfully hit. 
    // Additional info: print msgp->msg_controllen inside gdb is 0. 
    struct cmsghdr *cmsg; 
    for (cmsg = CMSG_FIRSTHDR(msgp); 
     cmsg != NULL; 
     cmsg = CMSG_NXTHDR(msgp, cmsg)) 
    { 
    printf("Time GOT!\n"); // <-- This line is not hit. 
    if ((cmsg->cmsg_level == SOL_SOCKET) 
     &&(cmsg->cmsg_type == SO_TIMESTAMPING)) 
     printf("TIME GOT2\n");// <-- of course , this line is not hit 
    } 

}

任何想法,为什么没有时间戳可以在这里找到?谢谢

解决方案 我能够得到软件时间戳和硬件时间戳使用onload与solarflare NIC。 还不知道如何单独获取软件时间戳。

+0

我怀疑'SO_TIMESTAMPING'是正确的值相匹配'与cmsg_type'。 – Igor

+0

对不起,我没有明白你的意思。你能否更详细些? – FaceBro

+0

没关系。还有其他问题。编译您的代码,并打开所有警告并共享编译输出以及程序输出。 – Igor

回答

2

你给了,在年底的评论的链接,说:

I've discovered why it doesn't work. SIOCGSTAMP only works for UDP 
packets or RAW sockets, but does not work for TCP. – Gio Mar 17 '16 at 9:331  

it doesn't make sense to ask for timestamps for TCP, because there's 
no direct correlation between arriving packets and data becoming 
available. If you really want timestamps for TCP you'll have to use 
RAW sockets and implement your own TCP stack (or use a userspace TCP 
library). – ecatmur Jul 4 '16 at 10:39 
+0

我在内核文档的末尾没有找到你提到的评论。而且我实际上经过了几次文档,TCP时间戳被支持,如1.4节所述。 – FaceBro

+0

我不认为上面的链接末尾有评论。你能告诉哪里找到上面的评论? 1.4节明确指出,虽然支持TCP timstamp。 – FaceBro

+0

这个答案来自另一个SO线程https://stackoverflow.com/questions/36041740/obtain-packet-timestamp-through-ioctl-call-on-socket-file-descriptor 我非常怀疑这些评论的权威。需要更多权限。 – FaceBro