gettimeofday的man说明:
可以看出,使用这种方式计时,精度可达微秒,也就是10-6秒。进行计时的时候,我们需要前后调用两次gettimeofday,然后计算中间的差值:以下是写的一个小函数,客户端发送一个8K的数据给服务器,利用gettimeofday函数判断一次发送所需要的时间,也就是send()函数的一次调用时间。下面分别给出客户端和服务端的代码,客户端是可以链接TCP和UDP的客户端。中文注释有问题,我懒,不弄了,函数大家都能看得懂的。socket编程基础代码。
/*ŽòÓ¡ÃüÁîÐвÎÊýÓ÷š*/
void useage()
{
printf("Command Error - ./filename [tcp] [ip_address] [port]/n");
printf(" ./filename [udp] [ip_address] [port]/n");
exit(1);
}
/*************************************************
Function: tcpclient
Description: tcp¿Í»§¶Ë£¬Á¬œÓ³É¹Šºó·¢ËÍÐÅÏ¢žøtcp·þÎñÆ÷
Input: ·þÎñÆ÷ipµØÖ·ip_address £¬·þÎñÆ÷¶Ë¿Úport (¶ŒÊÇcharÐÍ)
Output: ÎÞ
Return: ³É¹Š·µ»Ø0£»Ê§°Ü·µ»Ø-1
*************************************************/
int tcpclient(char *ip_address ,char *port)
{
printf("ipaddress :%s/n port :%s/n",ip_address,port);
struct sockaddr_in server; /*serverÌלÓ×ÖµØÖ·œá¹¹*/
int sockfd;
int ret;
int i_port = atoi(port); /*×Ö·ûŽ®×ª»»ÕûÐÍ*/
char msgbuf[MAXDATASIZE];
struct timeval start;
struct timeval end;
struct timezone tz;
/*socket*/
sockfd = socket(AF_INET, SOCK_STREAM , 0);
if(sockfd < 0)
{
perror("data stream socket create failed!/n");
return -1;
}
server.sin_family = AF_INET; /*ipv4*/
i_port = atoi(port);
server.sin_port = htons(i_port); /*°ó¶š¶Ë¿Ú*/
/*°ó¶šipµØÖ·*/
ret = inet_pton(AF_INET, ip_address, &server.sin_addr.s_addr);
if (ret <= 0)
{
printf("your ip address is unvalide!/n");
useage();
}
/*connect*/
ret = connect(sockfd,(struct sockaddr*) &server,sizeof(struct sockaddr_in));
if(ret < 0)
{
perror("data connection is failed!/n");
return -1;
}
printf("connect to server successfully!/n");
while(1)
{
memset(msgbuf, 0, sizeof(msgbuf));
/*send message to server*/
gettimeofday(&start, &tz);
ret = send(sockfd, msgbuf, sizeof(msgbuf), 0);
gettimeofday(&end, &tz);
if(ret == -1)
{
perror("send error");
return -1;
}
printf("The time between 'send' = %d u_secs/n",end.tv_usec-start.tv_usec);
//printf("send message sucessfully!/n");
}
}
/*************************************************
Function: udpclient
Description: udp¿Í»§¶Ë£¬Á¬œÓ³É¹Šºó·¢ËÍÐÅÏ¢žøudp·þÎñÆ÷
Input: ·þÎñÆ÷ipµØÖ·ip_address £¬·þÎñÆ÷¶Ë¿Úport (¶ŒÊÇcharÐÍ)
Output: ÎÞ
Return: ³É¹Š·µ»Ø0£»Ê§°Ü·µ»Ø-1
*************************************************/
int udpclient(char *ip_address ,char *port)
{
struct sockaddr_in server, client;
int clientfd;
int ret;
int server_port = atoi(port); /*×Ö·ûŽ®×ªÕûÐÍ*/
int client_port = 50000;
char msgbuf[]="This is a message from udp client/n";
server.sin_family = AF_INET;
server.sin_port = htons(server_port);
ret = inet_pton(AF_INET, ip_address, &server.sin_addr.s_addr);
if (ret <= 0)
{
printf("your ip address is unvalide!/n");
useage();
}
client.sin_family = AF_INET;
client.sin_port = htons(client_port);
client.sin_addr.s_addr = INADDR_ANY;
/*socket*/
clientfd = socket(AF_INET ,SOCK_DGRAM ,0);
if ( -1 == clientfd )
{
printf("create socket failed/n");
return -1;
}
/*bind*/
ret = bind(clientfd, (struct sockaddr *)&client, sizeof(client));
if ( -1 == ret)
{
printf("bind failed /n");
return -1;
}
printf("connect to server sucessfully!/n");
/*send message to server*/
ret = sendto(clientfd, msgbuf, sizeof(msgbuf), 0, (struct sockaddr*)&server, sizeof(server));
if(ret == -1)
{
perror("send to server");
return -1;
}
printf("send message sucessfully/n");
}
int main(int argc ,char **argv)
{
/*ÅжÏÃüÁîÐвÎÊý*/
if(argc != 4)
{
useage();
}
/*²ÎÊý1Ϊtcp£¬µ÷ÓÃtcpclient*/
if(strcmp(argv[1],"tcp") == 0)
{
tcpclient(argv[2] ,argv[3]);
}
/*²ÎÊý1Ϊudp£¬µ÷ÓÃudpclient*/
else if(strcmp(argv[1],"udp") == 0)
{
udpclient(argv[2] ,argv[3]);
}
else
{
useage();
exit(1);
}
return 0;
}
struct sockaddr_in server_sockaddr; /*Ö÷»úœá¹¹*/
struct sockaddr_in client_sockaddr; /*¿Í»§¶Ëœá¹¹*/
int addrlen = sizeof(struct sockaddr_in); /*µØÖ·œá¹¹×ÖœÚÊý*/
int recvbytes;
int sockfd;
int new_sockfd;
char buf[MAXDATASIZE];
/*socket*/
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
printf("socket success!, socket id = %d/n", sockfd);
server_sockaddr.sin_family = AF_INET;
server_sockaddr.sin_port = htons(atoi(argv[1]));
server_sockaddr.sin_addr.s_addr = INADDR_ANY; /*ÈÎÒâµØÖ·*/
/*bind*/
if(bind(sockfd, (struct sockaddr*)&server_sockaddr, sizeof(struct sockaddr)) == -1)
{
perror("bind");
exit(1);
}
printf("bind success!/n");
/*listen*/
if(listen(sockfd, MAXCONN) == -1)
{
perror("listen");
exit(1);
}
printf("listening.../n");
/*accept*/
if((new_sockfd = accept(sockfd, (struct sockaddr*)&client_sockaddr, &addrlen)) == -1)
{
perror("accept");
exit(1);
}
while(1)
{
memset(buf, 0, sizeof(buf));
/*recvœÓÊÜ¿Í»§¶ËµÄÐÅÏ¢*/
if((recvbytes = recv(new_sockfd, buf, MAXDATASIZE, 0)) == -1)
{
perror("recv");
exit(1);
}
printf("received data size :%d/n", recvbytes);
}
close(sockfd);
return 0;
}
send文件可以打印出来每次时间,微妙级的精确计时工具,但是还有一个问题就是最后一次时间的输出实际上是第二个gettimeofday的调用后时间,这样实际上多加了一次gettimeofday的时间,应该是不够精准的,后续继续思考吧。希望看到的高人们给与指点…… ^_^!!