2017-05-26 150 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