【发布时间】:2017-10-27 07:27:12
【问题描述】:
- 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
}
}
任何想法为什么这里没有可用的时间戳?谢谢
解决方案 我可以使用带有 solarflare NIC 的 onload 来获取软件时间戳和硬件时间戳。 仍然不知道如何单独获取软件时间戳。
【问题讨论】:
-
我怀疑
SO_TIMESTAMPING是匹配cmsg_type的正确值。 -
对不起,我没有明白你的意思。能详细点吗?
-
没关系。还有其他问题。编译您的代码并打开所有警告并共享构建输出以及程序的输出。
-
这只是整个服务器代码的一部分,不过你可以不费吹灰之力地构建它。
-
@Igor 啊,我明白你的第一条评论的意思。但问题是一开始就没有匹配 cmsg_type 的 cmsg,没有返回控制 msg。
标签: sockets tcp linux-kernel timestamp setsockopt