zoukankan      html  css  js  c++  java
  • 再议socket

    再议socket

    线程池

    socket通道在内核中实际上只有一条,多个文件描述符指向同一个socket通道

    本地套接字(类似于管道,两个进程的通信)

    绑定是和磁盘文件绑定。

    #include <stdlib.h>
    #include <stdio.h>
    #include <stddef.h>
    #include <sys/socket.h>
    #include <sys/un.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    
    #define QLEN 10
    
    /*
     * Create a server endpoint of a connection.
     * Returns fd if all OK, <0 on error.
     */
    int serv_listen(const char *name)
    {
        int fd, len, err, rval;
        struct sockaddr_un un;
    
        /* create a UNIX domain stream socket */
        if ((fd = socket(AF_UNIX, SOCK_STREAM, 0) < 0))
        return(-1);
        unlink(name);   /* in case it already exists */
    
        /* fill in socket address structure */
        memset(&un, 0, sizeof(un));
        un.sun_family = AF_UNIX;
        strcpy(un.sun_path, name);
        len = offsetof(struct sockaddr_un, sun_path) + strlen(name);
    
        /* bind the name to the descriptor */
        if (bind(fd, (struct sockaddr *)&un, len) < 0)
        {
        rval = -2;
        goto errout;
        }
        if (listen(fd, QLEN) < 0)
        {
        rval = -3;
        goto errout;
        }
        return(fd);
    
    errout:
        err = errno;
        close(fd);
        errno = err;
        return(rval);
    }
    int serv_accept(int listenfd, uid_t *uidptr)
    {
        int clifd, len, err, rval;
        struct sockaddr_un un;
        struct stat statbuf;
        
        len = sizeof(un);
        if ((clifd = accept(listenfd, (struct sockaddr *)&un, &len)) < 0)
        return(-1);    /* often errno=EINTR, if signal caught */
    
        /* obtain the client's uid from its calling address */
        len -= offsetof(struct sockaddr_un, sun_path);  /* len of pathname */
        un.sun_path[len] = '';    /* null terminate */
    
        if (stat(un.sun_path, &statbuf) < 0)
        {
        rval = -2;
        goto errout;
        }
        if (S_ISSOCK(statbuf.st_mode) == 0)
        {
        rval = -3;  /* not a socket */
        goto errout;
        }
        if (uidptr != NULL)
        *uidptr = statbuf.st_uid;   /* return uid of caller */
        unlink(un.sun_path);    /* we're done with pathname now */
        return(clifd);
    
    errout:
        err = errno;
        close(clifd);
        errno = err;
        return(rval);
    }
    int main(void)
    {
        int lfd, cfd, n, i;
        uid_t cuid;
        char buf[1024];
    
        lfd = serv_listen("foo.socket");
        if (lfd < 0)
        {
        switch (lfd)
        {
            case -3:perror("listen"); break;
            case -2:perror("bind"); break;
            case -1:perror("socket"); break;
        }
        exit(-1);
        }
        cfd = serv_accept(lfd, &cuid); 
        if (cfd < 0)
        {
        switch (cfd)
        {
            case -3:perror("not a socket"); break;
            case -2:perror("a bad filename"); break;
            case -1:perror("accept"); break;
        }
        exit(-1);
        }
        while (1)
        {
    r_again:
        n = read(cfd, buf, 1024);
        if (n == -1)
        {
            if (errno == EINTR)
            goto r_again;
        }
        else if (n == 0)
        {
            printf("the other side has been closed.
    ");
            break;
        }
        for (i = 0; i < n; i++)
            buf[i] = toupper(buf[i]);
        write(cfd, buf, n);
        }
        close(cfd);
        close(lfd);
        return 0;
    }
    //客户端
    #include <stdio.h> #include <stdlib.h> #include <stddef.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #include <errno.h> #define CLI_PATH "/var/tmp/" /* +5 for pid = 14 chars */ /* * Create a client endpoint and connect to a server. * Returns fd if all OK, <0 on error. */ int cli_conn(const char *name) { int fd, len, err, rval; struct sockaddr_un un; /* create a UNIX domain stream socket */ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) return(-1); /* fill socket address structure with our address */ memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; sprintf(un.sun_path, "%s%05d", CLI_PATH, getpid()); len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path); unlink(un.sun_path); /* in case it already exists */ if (bind(fd, (struct sockaddr *)&un, len) < 0) { rval = -2; goto errout; } /* fill socket address structure with server's address */ memset(&un, 0, sizeof(un)); un.sun_family = AF_UNIX; strcpy(un.sun_path, name); len = offsetof(struct sockaddr_un, sun_path) + strlen(name); if (connect(fd, (struct sockaddr *)&un, len) < 0) { rval = -3; goto errout; } return(fd); errout: err = errno; close(fd); errno = err; return(rval); } int main(void) { int fd, n; char buf[1024]; fd = cli_conn("foo.socket"); if (fd < 0) { switch (fd) { case -3:perror("connect"); break; case -2:perror("bind"); break; case -1:perror("socket"); break; } exit(-1); } while (fgets(buf, sizeof(buf), stdin) != NULL) { write(fd, buf, strlen(buf)); n = read(fd, buf, sizeof(buf)); write(STDOUT_FILENO, buf, n); } close(fd); return 0; }
  • 相关阅读:
    POJ 3258 (NOIP2015 D2T1跳石头)
    POJ 3122 二分
    POJ 3104 二分
    POJ 1995 快速幂
    409. Longest Palindrome
    389. Find the Difference
    381. Insert Delete GetRandom O(1)
    380. Insert Delete GetRandom O(1)
    355. Design Twitter
    347. Top K Frequent Elements (sort map)
  • 原文地址:https://www.cnblogs.com/rainbow1122/p/8118974.html
Copyright © 2011-2022 走看看