⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket.c

📁 linux下的获取Internet time的程式
💻 C
字号:
/*  Copyright (C) 1996, 2000 N.M. Maclaren    Copyright (C) 1996, 2000 The University of CambridgeThis includes all of the code needed to handle Berkeley sockets.  It is wayoutside current POSIX, unfortunately.  It should be easy to convert to a systemthat uses another mechanism.  It does not currently use socklen_t, becausethe only system that the author uses that has it is Linux. */#include "header.h"#include "internet.h"#include <fcntl.h>#include <errno.h>#define SOCKET#include "kludges.h"#undef SOCKET/* The code needs to set some variables during the open, for use by laterfunctions. */static int initial = 1,    descriptors[MAX_SOCKETS];static struct sockaddr_in here[MAX_SOCKETS], there[MAX_SOCKETS];/* There needs to be some disgusting grobble for handling timeouts, that isidentical to the grobble in internet.c. */static jmp_buf jump_buffer;static void jump_handler (int sig) {    longjmp(jump_buffer,1);}static int clear_alarm (void) {    int k;    k = errno;    alarm(0);    errno = 0;    if (signal(SIGALRM,SIG_DFL) == SIG_ERR) {        fatal(errno,"unable to reset signal handler",NULL);        return errno;    }    errno = k;    return 0;}void display_in_hex (const void *data, int length) {    int i;    for (i = 0; i < length; ++i)        fprintf(stderr,"%.2x",((const unsigned char *)data)[i]);}int open_socket (int which, char *hostname, int timespan) {/* Locate the specified NTP server, set up a couple of addresses and open asocket. */    int port, k;    struct in_addr address, anywhere, everywhere;/* Initialise and find out the server and port number.  Note that the portnumber is in network format. */    if (initial) for (k = 0; k < MAX_SOCKETS; ++k) descriptors[k] = -1;    initial = 0;    if (which < 0 || which >= MAX_SOCKETS || descriptors[which] >= 0) {        fatal(EMSNTP_INTERNAL,"socket index out of range or already open",NULL);        return EMSNTP_INTERNAL;    }    if (verbose > 2) fprintf(stderr,"Looking for the socket addresses\n");    find_address(&address,&anywhere,&everywhere,&port,hostname,timespan);    if (verbose > 2) {        fprintf(stderr,"Internet address: address=");        display_in_hex(&address,sizeof(struct in_addr));        fprintf(stderr," anywhere=");        display_in_hex(&anywhere,sizeof(struct in_addr));        fprintf(stderr," everywhere=");        display_in_hex(&everywhere,sizeof(struct in_addr));        fputc('\n',stderr);    }/* Set up our own and the target addresses.  Note that the target address willbe reset before use in server mode. */    memset(&here[which],0,sizeof(struct sockaddr_in));    here[which].sin_family = AF_INET;    here[which].sin_port =        (operation == op_listen || operation == op_server ? port : 0);    here[which].sin_addr = anywhere;    memset(&there[which],0,sizeof(struct sockaddr_in));    there[which].sin_family = AF_INET;    there[which].sin_port = port;    there[which].sin_addr = (operation == op_broadcast ? everywhere : address);    if (verbose > 2) {        fprintf(stderr,"Initial sockets: here=");        display_in_hex(&here[which].sin_addr,sizeof(struct in_addr));        fputc('/',stderr);        display_in_hex(&here[which].sin_port,sizeof(here[which].sin_port));        fprintf(stderr," there=");        display_in_hex(&there[which].sin_addr,sizeof(struct in_addr));        fputc('/',stderr);        display_in_hex(&there[which].sin_port,sizeof(there[which].sin_port));        fputc('\n',stderr);    }/* Allocate a local UDP socket and configure it. */    errno = 0;    if ((descriptors[which] = socket(AF_INET,SOCK_DGRAM,0)) < 0 ||            bind(descriptors[which],(struct sockaddr *)&here[which],                    sizeof(here[which]))  < 0) {        fatal(errno,"unable to allocate socket for NTP",NULL);        return errno;    }    if (operation == op_broadcast) {        errno = 0;        k = setsockopt(descriptors[which],SOL_SOCKET,SO_BROADCAST,                (void *)&k,sizeof(k));        if (k != 0) {            fatal(errno,"unable to set permission to broadcast",NULL);            return errno;        }    }    return 0;}extern int write_socket (int which, void *packet, int length) {/* Any errors in doing this are fatal - including blocking.  Yes, this leaves aserver vulnerable to a denial of service attack. */    int k;    if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0) {        fatal(EMSNTP_INTERNAL,"socket index out of range or not open",NULL);        return EMSNTP_INTERNAL;    }    errno = 0;    k = sendto(descriptors[which],packet,(size_t)length,0,            (struct sockaddr *)&there[which],sizeof(there[which]));    if (k != length) {        fatal(errno,"unable to send NTP packet",NULL);        return errno;    }    return 0;}extern int read_socket (int which, void *packet, int length, int waiting,                        int *written) {/* Read a packet and returns (in a parameter) the number of bytes written. Onlyincorrect length and timeout are not fatal. */    struct sockaddr_in scratch, *ptr;    int n;    int k;    *written = 0;/* Under normal circumstances, set up a timeout. */    if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0) {        fatal(EMSNTP_INTERNAL,"socket index out of range or not open",NULL);        return EMSNTP_INTERNAL;    }    if (waiting > 0) {        if (setjmp(jump_buffer)) {            if (verbose > 2)                fprintf(stderr,"Receive timed out\n");            else if (verbose > 1)                fprintf(stderr,"%s: receive timed out after %d seconds\n",                    argv0,waiting);            return -1;        }        errno = 0;        if (signal(SIGALRM,jump_handler) == SIG_ERR) {            fatal(errno,"unable to set up signal handler",NULL);            return errno;        }        alarm((unsigned int)waiting);    }/* Get the packet and clear the timeout, if any.  */    if (operation == op_server)        memcpy(ptr = &there[which],&here[which],sizeof(struct sockaddr_in));    else        memcpy(ptr = &scratch,&there[which],sizeof(struct sockaddr_in));    n = sizeof(struct sockaddr_in);    errno = 0;    k = recvfrom(descriptors[which],packet,(size_t)length,0,        (struct sockaddr *)ptr,&n);    if (waiting > 0) clear_alarm();/* Now issue some low-level diagnostics. */    if (k <= 0) {        fatal(errno,"unable to receive NTP packet from server",NULL);        return errno;    }    if (verbose > 2) {        fprintf(stderr,"Packet of length %d received from ",k);        display_in_hex(&ptr->sin_addr,sizeof(struct in_addr));        fputc('/',stderr);        display_in_hex(&ptr->sin_port,sizeof(ptr->sin_port));        fputc('\n',stderr);    }    *written = k;    return 0;}extern int flush_socket (int which, int *count) {/* Get rid of any outstanding input, because it may have been hanging aroundfor a while.  Ignore packet length oddities and return the number of packetsskipped. */    struct sockaddr_in scratch;    int n;    char buffer[256];    int flags, total = 0, k;    *count = 0;/* The code is the obvious. */    if (which < 0 || which >= MAX_SOCKETS || descriptors[which] < 0) {        fatal(EMSNTP_INTERNAL,"socket index out of range or not open",NULL);        return EMSNTP_INTERNAL;    }    if (verbose > 2) fprintf(stderr,"Flushing outstanding packets\n");    errno = 0;    if ((flags = fcntl(descriptors[which],F_GETFL,0)) < 0 ||        fcntl(descriptors[which],F_SETFL,flags|O_NONBLOCK) == -1) {        fatal(errno,"unable to set non-blocking mode",NULL);        return errno;    }    while (1) {        n = sizeof(struct sockaddr_in);        errno = 0;        k = recvfrom(descriptors[which],buffer,256,0,            (struct sockaddr *)&scratch,&n);        if (k < 0) {            if (errno == EAGAIN || errno == EWOULDBLOCK) break;            fatal(errno,"unable to flush socket",NULL);            return errno;        }        ++*count;        total += k;    }    errno = 0;    if (fcntl(descriptors[which],F_SETFL,flags) == -1) {        fatal(errno,"unable to restore blocking mode",NULL);        return errno;    }    if (verbose > 2)        fprintf(stderr,"Flushed %d packets totalling %d bytes\n",*count,total);    return 0;}extern int close_socket (int which) {/* There is little point in shielding this with a timeout, because any hangsare unlikely to be interruptible.  It can get called when the sockets haven'tbeen opened, so ignore that case. */    if (which < 0 || which >= MAX_SOCKETS) {        fatal(EMSNTP_INTERNAL,"socket index out of range",NULL);        return EMSNTP_INTERNAL;    }    if (descriptors[which] < 0) return;    errno = 0;    if (close(descriptors[which])) {        fatal(errno,"unable to close NTP socket",NULL);        return errno;    }    descriptors[which] = -1;    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -