86-时间获取客户端

本文来一点比较轻松的话题,来写一个客户端,从时间服务器(daytime server) 上取得时间并打印。

1. daytime 服务器

daytime 服务器我们不用自己写了,这个网站列举了很多现成的 daytime 服务器地址:http://tf.nist.gov/tf-cgi/servers.cgi , 剩下的事情我们就只管写客户端。

daytime 服务器使用的是 TCP 协议,默认端口是 13。

目前测得可用的 daytime 服务器有下面几个(不同时间段可能会不一样):

sttime.carsoncity.k12.mi.us
wwv.nist.gov                   
time.nist.gov                  
utcnist.colorado.edu
time-d.nist.gov

其它的服务器在网络状况好的情况下可以访问,差的情况下也总是出现连接超时的情况。具体看网络环境吧。

2. 时间获取客户端

非常简单,客户端连接上 daytime 服务器后,直接从套接字 read 就行了,然后将读取到的数据打印在屏幕上。

本文使用的程序托管在 gitos 上:http://git.oschina.net/ivan_allen/unp

如果你已经 clone 过这个代码了,请使用 git pull 更新一下。本节程序所使用的程序路径是 unp/program/nonblockio/biotimecli.

代码不长,直接贴出来:

#include "common.h"            

char hostname[64];             
int port;

void client_routine();         
void doClient(int sockfd);     

int main(int argc, char* argv[]) {
  Args args = parsecmdline(argc, argv);

  WARNING("Usage: %s [-h hostname] [-p port]\n", argv[0]);
  // 随便选了一个默认的
  SETSTR(args, hostname, "h", "nisttime.carsoncity.k12.mi.us");
  SETINT(args, port, "p", 13);

  client_routine();
}

void client_routine() {
  int ret, sockfd;
  struct sockaddr_in servaddr;

  ret = resolve(hostname, port, &servaddr);
  if (ret < 0) ERR_EXIT("resolve");

  sockfd = socket(AF_INET, SOCK_STREAM, 0);
  if (sockfd < 0) ERR_EXIT("socket");

  // 连接服务器
  ret = connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));
  if (ret < 0) ERR_EXIT("socket");

  doClient(sockfd);
  close(sockfd);
}

void doClient(int sockfd) {
  char buf[4096];
  int nr;

  while(1) {
    nr = iread(sockfd, buf, 4096);
    if (nr < 0) ERR_EXIT("iread");
    else if (nr == 0) {
      break;
    }
    else {
      writen(STDOUT_FILENO, buf, nr);
    }
  }
}

3. 实验

3.1 实验一:正常情况


这里写图片描述
图1 可以正常获取到时间

可以看到,整个程序的运行时间约为 926 ms,毕竟这个服务器(nisttime.carsoncity.k12.mi.us)都在美国 Georgia 州的 Macon 市,所以有点慢。

3.2 实验二:连接超时


这里写图片描述
图2 连接超时

这次特意选了一个连接超时的,可以看到整个过程持续了约 127 s 左右。

注:早上我连接 wolfnisttime.com 的时候是不超时的,这应该和网络环境有关。如果你实验的时候连接成功也不要奇怪,只能说明你运气太好^_^

4. 总结

编写这个客户端的目的,是为了引出下一个知识点——非阻塞 i/o 上调用 connect. 不同于非阻塞 i/o 读写,在非阻塞 i/o 上调用 connect 要复杂的多。

  • 掌握时间获取客户端编写
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值