Linux TCP 套接字时间戳选项

Fac*_*Bro 5 sockets timestamp tcp linux-kernel setsockopt

引用此在线内核文档

  • 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
  } 
Run Code Online (Sandbox Code Playgroud)

}

有什么想法为什么这里没有可用的时间戳吗?谢谢

解决方案 我可以使用带有 Solarflare NIC 的 onload 来获取软件时间戳和硬件时间戳。仍然不知道如何单独获取软件时间戳。

mik*_*kep 2

您在最后的评论中给出的链接说:

\n\n
I've discovered why it doesn't work. SIOCGSTAMP only works for UDP\npackets or RAW sockets, but does not work for TCP. \xe2\x80\x93 Gio Mar 17 '16 at 9:331    \n\nit doesn't make sense to ask for timestamps for TCP, because there's\nno direct correlation between arriving packets and data becoming \navailable. If you really want timestamps for TCP you'll have to use \nRAW sockets and implement your own TCP stack (or use a userspace TCP\nlibrary). \xe2\x80\x93 ecatmur Jul 4 '16 at 10:39 \n
Run Code Online (Sandbox Code Playgroud)\n