note of unp

来源:互联网 发布:移动网络类型gsm 编辑:程序博客网 时间:2024/05/02 14:48

UNIX Network Programming is the first choice if you want to learn network program. I am learning it and do some reading notes of this book.

The first sample of this book is used to show how to connect to server with socket.

#include <sys/socket.h>#include <arpa/inet.h>#import <stdio.h>#import <unistd.h>#include <netinet/in.h>#define MAXLINE 4096#define SA struct sockaddrint main(int argc, char **argv){    int sockfd, n;    char recvline[MAXLINE + 1];    struct sockaddr_in servaddr;    if (argc != 2){        printf("usage: a.out <IPaddress>");    }    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){        printf("socket error");    }    bzero(&servaddr, sizeof(servaddr));    servaddr.sin_family = AF_INET;    servaddr.sin_port = htons(58862);    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)        printf("inet_pton error for %s", argv[1]);    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) printf("connect error");    while ( (n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; /* null terminate */        if (fputs(recvline, stdout) == EOF)            printf("fputs error");    } if(n<0)        printf("read error");    exit(0);}

You can compile it in your compiler such as gcc,clang.
I am interesting in the function of bzero,whose function is set the memory or string zero.there is no source code in libc because the function is not in it.Fortunately we can get it in function “memset”,whose source code as follows :

# define op_t   unsigned long int# define OPSIZ  (sizeof(op_t))typedef unsigned char byte;void* memset (void *dstpp, int c, size_t len){   long int dstp = (long int) dstpp;   if (len >= 8){      size_t xlen;      op_t cccc;      cccc = (unsigned char) c;      cccc |= cccc << 8;      cccc |= cccc << 16;      if (OPSIZ > 4)        /* Do the shift in two steps to avoid warning if long has 32 bits.  */        cccc |= (cccc << 16) << 16;      /* There are at least some bytes to set.       No need to test for LEN == 0 in this alignment loop.  */      while (dstp % OPSIZ != 0){            ((byte *) dstp)[0] = c;            dstp += 1;            len -= 1;        }      /* Write 8 `op_t' per iteration until less than 8 `op_t' remain.  */      xlen = len / (OPSIZ * 8);      while (xlen > 0){          ((op_t *) dstp)[0] = cccc;          ((op_t *) dstp)[1] = cccc;          ((op_t *) dstp)[2] = cccc;          ((op_t *) dstp)[3] = cccc;          ((op_t *) dstp)[4] = cccc;          ((op_t *) dstp)[5] = cccc;          ((op_t *) dstp)[6] = cccc;          ((op_t *) dstp)[7] = cccc;          dstp += 8 * OPSIZ;          xlen -= 1;        }      len %= OPSIZ * 8;      /* Write 1 `op_t' per iteration until less than OPSIZ bytes remain.  */      xlen = len / OPSIZ;      while (xlen > 0){            ((op_t *) dstp)[0] = cccc;            dstp += OPSIZ;            xlen -= 1;          }      len %= OPSIZ;    }    /* Write the last few bytes.  */    while (len > 0){        ((byte *) dstp)[0] = c;        dstp += 1;        len -= 1;    }    return dstpp;}

It seems too hard for me to understand these code,so put it here so I can refer to it.
Next function I want to see source code is function of “inet_pton”,the source code is

#define NS_INADDRSZ  4static int my_inet_pton4(const char *src, u_char *dst, int pton){    u_int32_t val;    u_int digit, base;    ptrdiff_t n;    unsigned char c;    u_int parts[4];    u_int *pp = parts;    c = *src;    for (;;) {        /*         * Collect number up to ``.''.         * Values are specified as for C:         * 0x=hex, 0=octal, isdigit=decimal.         */        if (!isdigit(c))            return (0);        val = 0; base = 10;        if (c == '0') {            c = *++src;            if (c == 'x' || c == 'X')                base = 16, c = *++src;            else if (isdigit(c) && c != '9')                base = 8;        }        /* inet_pton() takes decimal only */        if (pton && base != 10)            return (0);        for (;;) {            if (isdigit(c)) {                digit = c - '0';                if (digit >= base)                    break;                val = (val * base) + digit;                c = *++src;            } else if (base == 16 && isxdigit(c)) {                digit = c + 10 - (islower(c) ? 'a' : 'A');                if (digit >= 16)                    break;                val = (val << 4) | digit;                c = *++src;            } else                break;        }        if (c == '.') {            /*             * Internet format:             *  a.b.c.d             *  a.b.c   (with c treated as 16 bits)             *  a.b (with b treated as 24 bits)             *  a   (with a treated as 32 bits)             */            if (pp >= parts + 3)                return (0);            *pp++ = val;            c = *++src;        } else            break;    }    /*     * Check for trailing characters.     */    if (c != '\0' && !isspace(c))        return (0);    /*     * Concoct the address according to     * the number of parts specified.     */    n = pp - parts + 1;    /* inet_pton() takes dotted-quad only.  it does not take shorthand. */    if (pton && n != 4)        return (0);    switch (n) {        case 0:            return (0);     /* initial nondigit */        case 1:             /* a -- 32 bits */            break;        case 2:             /* a.b -- 8.24 bits */            if (parts[0] > 0xff || val > 0xffffff)                return (0);            val |= parts[0] << 24;            break;        case 3:             /* a.b.c -- 8.8.16 bits */            if ((parts[0] | parts[1]) > 0xff || val > 0xffff)                return (0);            val |= (parts[0] << 24) | (parts[1] << 16);            break;        case 4:             /* a.b.c.d -- 8.8.8.8 bits */            if ((parts[0] | parts[1] | parts[2] | val) > 0xff)                return (0);            val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);            break;    }    if (dst) {        val = htonl(val);        memcpy(dst, &val, NS_INADDRSZ);    }    return (1);}/*demo*/int main(){    in_addr_t dstchar;    char *srcChar = "192.168.1.1";    my_inet_pton4(srcChar,&dstchar,1);    return 0;}
0 0