if(pthread_create(&tid, NULL, start_routine, (void *)arg)) {
perror(\ error.\\n\ exit(-1); } }
close(listenfd); }
static pthread_key_t key;
static pthread_once_t once = PTHREAD_ONCE_INIT; struct DATA_THR { int index; };
static void key_destroy(void *buf) { free(buf); }
static void buffer_key_alloc() {
pthread_key_create(&key, key_destroy); }
void savedata(char *recvbuf, int len, char *cli_data) {
struct DATA_THR *data;
pthread_once(&once, buffer_key_alloc);
if ((data = (struct DATA_THR *)pthread_getspecific ( key )) == NULL) { data = (struct DATA_THR *) calloc (1, sizeof(struct DATA_THR)); pthread_setspecific (key, data); data -> index = 0; }
36
int i;
for (i=0; i
void process_client(int connectfd,struct sockaddr_in client){ char recvbuf[MAXCHARSIZE]; char sendbuf[MAXCHARSIZE]; char client_name[MAXCHARSIZE]; char client_data[5000]; int recvlen,i;
printf(\ send(connectfd,\ recvlen=recv(connectfd,client_name,MAXCHARSIZE,0); if(recvlen==0){ close(connectfd);
printf(\ return; }
else if(recvlen<0){ close(connectfd);
printf(\ return; }
client_name[recvlen]='\\0';
printf(\ bzero(recvbuf,1000);
while(recvlen=recv(connectfd,recvbuf,MAXCHARSIZE,0)){ savedata(recvbuf,recvlen,client_data); recvbuf[recvlen]='\\0';
printf(\ message:%s\\n\
37
for(i=0;i send(connectfd,sendbuf,strlen(sendbuf),0); bzero(recvbuf,1000); } /*while*/ printf(\ close(connectfd); } void *start_routine(void *arg) { struct ARG *info; info = (struct ARG *)arg; process_client(info -> connfd, info -> client); free(arg); pthread_exit(NULL); } \\n\38 实验六 实现NTP网络授时客户端 1. 实验目的 1.利用UDP协议实现NTP网络授时服务器; 2.使用select在NTP客户端中实现I/O复用; 2. 实验要求 1.认真阅读和掌握本实验的相关的知识点。 2.上机编写并运行本程序。 3.保存和打印出程序的运行结果,并结合程序进行分析。 3. 实验内容 1、阅读NTP协议,使用UDP连接NTP服务器,构建NTP协议包,向服务器发送客户数据,发送成功后显示发送数量,接收服务端的返回信息,要求客户端具有多路I/O复用的能力。只在数据接受完毕后读取数据。 2、根据NTP协议解析服务器返回的信息,从中获得服务器的准确时间,然后更新本地系统时间。 4. 实验内容程序 程序源代码: /* * ntp_client_by_other_main.c * * Created on: 2010-9-8 * Author: kerwin */ #include #include #define NTP_SERVER \#define NTP_PORT 123 39 // //rfc1305 defined from 1900 so also 2208988800 (1900 - 1970 ) seconds left // //timeval.tv_sec + JAN_1970 = timestamp.coarse #define JAN_1970 0x83aa7e80 //timeval.tv_usec=>timestamp.fine #define NTPFRAC(x) (4294 * (x) + ((1981 * (x))>>11)) //timeval.tv_usec<=timestamp.fine #define USEC(x) (((x) >> 12) - 759 * ((((x) >> 10) + 32768) >> 16)) #define Data(i) ntohl(((unsigned int *)data)[i]) #define LI 0 #define VN 3 #define MODE 3 #define STRATUM 0 #define POLL 4 #define PREC -6 struct ntptime { unsigned int coarse; unsigned int fine; }; void send_packet(int fd) { unsigned int data[12]; struct timeval now; int ret; if (sizeof(data) != 48) { fprintf(stderr, \ return; } memset((char*) data, 0, sizeof(data)); data[0] = htonl((LI << 30) | (VN << 27) | (MODE << 24) | (STRATUM << 16) | (POLL << 8) | (PREC & 0xff)); data[1] = htonl(1 << 16); /* Root Delay (seconds) */ data[2] = htonl(1 << 16); /* Root Dispersion (seconds) */ gettimeofday(&now, NULL); data[10] = htonl(now.tv_sec + JAN_1970); /* Transmit Timestamp coarse */ data[11] = htonl(NTPFRAC(now.tv_usec)); /* Transmit Timestamp fine */ 40