zoukankan      html  css  js  c++  java
  • Linux 网络编程: xinetd time

    前言

    终于把 xinetd 服务装好了,那就在来实现一下 TCP 协议从服务器和本机获取时间吧。那么多思想汇报还没写,我也是醉了。

    安装 xinetd

    apt-get install xinetd
    

    配置开启 time 服务

    vi /etc/xinetd.d/time
    

    disable = yes 改成 disable = no ,看注释很清楚 time 服务返回的是1900年1月1日到现在的秒数。如果没有写的权限,就要 chmod

    chmod 777 time
    

    重启 xinetd 服务

    service xinetd restart
    

    客户端

    errexit.c

    /* errexit.c - errexit */
    #include <stdarg.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    /*------------------------------------------------------------------------
     * errexit - print an error message and exit
     *------------------------------------------------------------------------
     */
    int errexit(const char *format, ...)
    {
    	va_list	args;
    
    	va_start(args, format);
    	vfprintf(stderr, format, args);
    	va_end(args);
    	exit(1);
    }
    

    errno.h

    /* Error constants.  Linux specific version.
       Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc.
       This file is part of the GNU C Library.
    
       The GNU C Library is free software; you can redistribute it and/or
       modify it under the terms of the GNU Lesser General Public
       License as published by the Free Software Foundation; either
       version 2.1 of the License, or (at your option) any later version.
    
       The GNU C Library is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       Lesser General Public License for more details.
    
       You should have received a copy of the GNU Lesser General Public
       License along with the GNU C Library; if not, write to the Free
       Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
       02111-1307 USA.  */
    
    #ifdef _ERRNO_H
    
    # undef EDOM
    # undef EILSEQ
    # undef ERANGE
    # include <linux/errno.h>
    
    /* Linux has no ENOTSUP error code.  */
    # define ENOTSUP EOPNOTSUPP
    
    /* Linux also had no ECANCELED error code.  Since it is not used here
       we define it to an invalid value.  */
    # ifndef ECANCELED
    #  define ECANCELED	125
    # endif
    
    # ifndef __ASSEMBLER__
    /* Function to get address of global `errno' variable.  */
    extern int *__errno_location (void) __THROW __attribute__ ((__const__));
    
    #  if !defined _LIBC || defined _LIBC_REENTRANT
    /* When using threads, errno is a per-thread value.  */
    #   define errno (*__errno_location ())
    #  endif
    # endif /* !__ASSEMBLER__ */
    #endif /* _ERRNO_H */
    
    #if !defined _ERRNO_H && defined __need_Emath
    /* This is ugly but the kernel header is not clean enough.  We must
       define only the values EDOM, EILSEQ and ERANGE in case __need_Emath is
       defined.  */
    # define EDOM	33	/* Math argument out of domain of function.  */
    # define EILSEQ	84	/* Illegal byte sequence.  */
    # define ERANGE	34	/* Math result not representable.  */
    #endif /* !_ERRNO_H && __need_Emath */
    

    connectsock.c

    /* connectsock.c - connectsock */
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <netdb.h>
    #include <string.h>
    #include <stdlib.h>
    
    #ifndef	INADDR_NONE
    #define	INADDR_NONE	0xffffffff
    #endif	/* INADDR_NONE */
    
    extern int	errno;
    
    int	errexit(const char *format, ...);
    
    /*------------------------------------------------------------------------
     * connectsock - allocate & connect a socket using TCP or UDP
     *------------------------------------------------------------------------
     */
    int connectsock(const char *host, const char *service, const char *transport )
    /*
     * Arguments:
     *      host      - name of host to which connection is desired
     *      service   - service associated with the desired port
     *      transport - name of transport protocol to use ("tcp" or "udp")
     */
    {
    	struct hostent	*phe;	/* pointer to host information entry	*/
    	struct servent	*pse;	/* pointer to service information entry	*/
    	struct protoent *ppe;	/* pointer to protocol information entry*/
    	struct sockaddr_in sin;	/* an Internet endpoint address		*/
    	int	s, type;	/* socket descriptor and socket type	*/
    
    
    	memset(&sin, 0, sizeof(sin));
    	sin.sin_family = AF_INET;
    
        /* Map service name to port number */
    	if ( pse = getservbyname(service, transport) )
    		sin.sin_port = pse->s_port;
    	else if ((sin.sin_port=htons((unsigned short)atoi(service))) == 0)
    		errexit("can't get "%s" service entry
    ", service);
    
        /* Map host name to IP address, allowing for dotted decimal */
    	if ( phe = gethostbyname(host) )
    		memcpy(&sin.sin_addr, phe->h_addr, phe->h_length);
    	else if ( (sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
    		errexit("can't get "%s" host entry
    ", host);
    
        /* Map transport protocol name to protocol number */
    	if ( (ppe = getprotobyname(transport)) == 0)
    		errexit("can't get "%s" protocol entry
    ", transport);
    
        /* Use protocol to choose a socket type */
    	if (strcmp(transport, "udp") == 0)
    		type = SOCK_DGRAM;
    	else
    		type = SOCK_STREAM;
    
        /* Allocate a socket */
    	s = socket(PF_INET, type, ppe->p_proto);
    	if (s < 0)
    		errexit("can't create socket: %s
    ", strerror(errno));
    
        /* Connect the socket */
    	if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
    		errexit("can't connect to %s.%s: %s
    ", host, service,
    			strerror(errno));
    	return s;
    }
    

    connectTCP.c

    /* connectTCP.c - connectTCP */
    
    int	connectsock(const char *host, const char *service,
    		const char *transport);
    
    /*------------------------------------------------------------------------
     * connectTCP - connect to a specified TCP service on a specified host
     *------------------------------------------------------------------------
     */
    int connectTCP(const char *host, const char *service )
    /*
     * Arguments:
     *      host    - name of host to which connection is desired
     *      service - service associated with the desired port
     */
    {
    	return connectsock( host, service, "tcp");
    }
    

    TCPtime.c

    /* TCPtime.c - TCPtime, main */
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    #include <stdio.h>
    #include <time.h>
    
    extern int      errno;
    
    int     TCPtime(const char *host, const char *service);
    int     errexit(const char *format, ...);
    int     connectTCP(const char *host, const char *service);
    
    #define LINELEN         128
    
    /*------------------------------------------------------------------------
     * main - TCP client for DAYTIME service
     *------------------------------------------------------------------------
     */
    int main(int argc, char *argv[])
    {
            char    *host1 = "localhost";    /* host to use if none supplied */
            char    *host2 = "localhost";    /* host to use if none supplied */
    
            switch (argc) {
            case 1:
                    host1 = "localhost";
                    host2 = "localhost";
                    break;
            case 2:
                    host2 = argv[1];
                    break;
            default:
                    fprintf(stderr, "The number of parameter is to much! Just need the other host~
    ");
                    exit(1);
            }
            TCPtime(host1, host2);
            exit(0);
    }
    
    /*------------------------------------------------------------------------
     * TCPtime - invoke Daytime on specified host and print results
     *------------------------------------------------------------------------
     */
    int TCPtime(const char *host1, const char *host2)
    {
        char    buf[LINELEN+1];         /* buffer for one line of text  */
        int     s1, s2, n;              /* socket, read count           */
        
        time_t  time1, time2;
    
        s1 = connectTCP(host1, "time");
        s2 = connectTCP(host2, "time");
        
        while( (n = read(s1, (char *)&time1, sizeof(time1))) > 0) {
    		time1 = ntohl((unsigned long)time1);
            time1 -= 2208988800UL;
            time1 += 4294967296UL;
            printf("time in %s is %s", host1, ctime(&time1));
        }
        
        while( (n = read(s2, (char *)&time2, sizeof(time2))) > 0) {
            time2 = ntohl((unsigned long long)time2);
            time2 -= 2208988800UL;
            time2 += 4294967296UL;
            printf("time in %s is %s", host2, ctime(&time2));
        }
        printf("the difference is %d seconds.
    ", abs(time1 - time2));
        return 0;
    }
    

    time_t 类型的长度在32位机器下是32位,在64位机器下是64位,所以在减去 2208988800UL 秒(变成1970年到现在的秒数)后,还要加上2的32次方秒。(我觉得如果能自己实现64位数的网络序转主机序应该也是可以实现的)。

    编译运行

  • 相关阅读:
    asp.net mvc 学习
    ms sqlserver 清除数据库日志脚本
    DB、ETL、DW、OLAP、DM、BI关系结构图
    日期维度(周一为每周第一天)
    关于C#操作Excel,复制Sheet的记录
    ms sqlserver 登录失败 错误:4064
    通过sqlserver sa密码修改windows操作系统密码
    ssas 为绑定指定的大小太小,导致一个或多个列值被截断
    ExpandoObject的使用
    【慕课网实战】Spark Streaming实时流处理项目实战笔记三之铭文升级版
  • 原文地址:https://www.cnblogs.com/pengzhendong/p/4914377.html
Copyright © 2011-2022 走看看