c++實現本地套接字使用

//client

#include <stdio.h>
#include <stddef.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <string>
#include <unistd.h>

/* Create a client endpoint and connect to a server.   Returns fd if all OK, <0 on error. */
int main()
{
    std::string server_name = "foo.sock";
    /* create a UNIX domain stream socket */
    int connfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (connfd < 0)    {
        return -1;
    }
    struct sockaddr_un un;
    memset(&un, 0, sizeof(un));            /* fill socket address structure with our address */
    un.sun_family = AF_UNIX;
    sprintf(un.sun_path, "scktmp%05d", getpid());
    int len = offsetof(struct sockaddr_un, sun_path) + strlen(un.sun_path);
    unlink(un.sun_path);               /* in case it already exists */
    if (bind(connfd, (struct sockaddr*) & un, len) < 0) {
         return - 1;
    }

    /* fill socket address structure with server's address */
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path, server_name.c_str());
    len = offsetof(struct sockaddr_un, sun_path) + strlen(server_name.c_str());
    if (connect(connfd, (struct sockaddr*) & un, len) < 0){
        return -1;
    }

    if (connfd < 0){
        printf("Error[%d] when connecting...", errno);
        return 0;
    }

    printf("Begin to recv/send...\n");
    char rvbuf[4096] = {0};
    for (int i = 0; i < 10; i++){
        //=========發送======================
        memset(rvbuf, 'a', 2048);
        rvbuf[2047] = 'b';
        int size = send(connfd, rvbuf, 2048, 0);
        if (size >= 0){
            printf("Data[%d] Sended:%c.\n", size, rvbuf[0]);
        }
        if (size == -1){
            printf("Error[%d] when Sending Data:%s.\n", errno, strerror(errno));
            break;
        }
        sleep(1);
    }
    
    close(connfd);
    printf("Client exited.\n");
}

//server

#include <stdio.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <errno.h>
#include <stddef.h>
#include <string>
#include <unistd.h>

// the max connection number of the server
#define MAX_CONNECTION_NUMBER 5

/* * Create a server endpoint of a connection. * Returns fd if all OK, <0 on error. */
int unix_socket_listen(const char* servername)
{
    int fd =socket(AF_UNIX, SOCK_STREAM, 0);
    if (fd < 0){
        return(-1);
    }

    struct sockaddr_un un;
    int rval =0;
    unlink(servername);               /* in case it already exists */
    memset(&un, 0, sizeof(un));
    un.sun_family = AF_UNIX;
    strcpy(un.sun_path, servername);
    int len = offsetof(struct sockaddr_un, sun_path) + strlen(servername);
    /* bind the name to the descriptor */
    if (bind(fd, (struct sockaddr*) & un, len) < 0)
    {
        rval = -2;
    }
    else
    {
        if (listen(fd, MAX_CONNECTION_NUMBER) < 0)
        {
            rval = -3;
        }
        else
        {
            return fd;
        }
    }
    int err;
    err = errno;
    close(fd);
    errno = err;
    return rval;
}

int unix_socket_accept(int listenfd, uid_t* uidptr)
{
    int clifd, len, rval;
    time_t staletime;
    struct sockaddr_un un;
    struct stat statbuf;
    len = sizeof(un);
    if ((clifd = accept(listenfd, (struct sockaddr*) & un, (socklen_t*)&len)) < 0)
    {
        return(-1);
    }
    /* obtain the client's uid from its calling address */
    len -= offsetof(struct sockaddr_un, sun_path);  /* len of pathname */
    un.sun_path[len] = 0; /* null terminate */
    if (stat(un.sun_path, &statbuf) < 0)
    {
        rval = -2;
    }
    else
    {
        if (S_ISSOCK(statbuf.st_mode))
        {
            if (uidptr != NULL) *uidptr = statbuf.st_uid;    /* return uid of caller */
            unlink(un.sun_path);       /* we're done with pathname now */
            return clifd;
        }
        else
        {
            rval = -3;     /* not a socket */
        }
    }
    int err;
    err = errno;
    close(clifd);
    errno = err;
    return(rval);
}

void unix_socket_close(int fd)
{
    close(fd);
}

int main(void)
{
    std::string str = "foo.sock";
    int listenfd, connfd;
    listenfd = unix_socket_listen(str.c_str());
    if (listenfd < 0){
        printf("Error[%d] when listening...\n", errno);
        return 0;
    }
    printf("Finished listening...\n", errno);
    uid_t uid;
    connfd = unix_socket_accept(listenfd, &uid);
    unix_socket_close(listenfd);
    if (connfd < 0)
    {
        printf("Error[%d] when accepting...\n", errno);
        return 0;
    }
    printf("Begin to recv/send...\n");
    int i, n, size;
    char rvbuf[804] = { 0 };
    while (1) {
        while ((size = recv(connfd, rvbuf, 804, 0) > 0)) {
            printf("Recieved Data[%d]:%c...%c\n", size, rvbuf[0], rvbuf[size - 1]);
        }

        unix_socket_close(connfd);
    }

    unix_socket_close(connfd);
    printf("Server exited.\n");
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章