Linux poll客户端

Linux poll客户端

源代码:pollClient.cpp

/*******************************************************
* pollClient.cpp
*
* Create on 2018-10-6
*   Author: yanxinchun
*
* g++ -o pollClient pollClient.cpp
*******************************************************/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/select.h>
#include <sys/time.h>
#include <signal.h>
#include <poll.h>

#define ERR_EXIT(m) \
    do {            \
        perror(m);    \
        exit(EXIT_FAILURE);    \
    } while(0)

typedef struct _packet_st {
    int len;
    char buf[1024];
} PACKET_st;

ssize_t readn(int fd, void *buf, size_t count)
{
    size_t nleft = count;
    ssize_t nread;
    char *bufp = (char*)buf;
    
    while(nleft > 0){
        if(nread = read(fd, bufp, nleft) < 0) {
            if(errno == EINTR) {
                continue;
            }
            return -1;
        }else if(nread == 0) {
            return count - nleft;
        }
        
        bufp += nread;
        nleft -= nread;
    }
    
    return count;
}

ssize_t writen(int fd, const void *buf, size_t count)
{
    size_t nleft = count;
    ssize_t nwritten;
    char *bufp = (char*)buf;
    
    while(nleft > 0) {
        if(nwritten = write(fd, bufp, nleft) < 0) {
            if(errno == EINTR) {
                continue;
            }
            return -1;
        }else if(nwritten == 0) {
            continue;
        }
        
        bufp += nwritten;
        nleft -= nwritten;
    }
    
    return count;
}

int getlocalip(char *ip) 
{
    char host[100] = {0};
    if(gethostname(host, sizeof(host)) < 0) {
        return -1;
    }

    struct hostent* hp;
    if((hp = gethostbyname(host)) == NULL) {
        return -1;
    }
    
    strcpy(ip, inet_ntoa(*(struct in_addr*)hp->h_addr_list[0]));
    //int i = 0;
    //while(hp->h_addr_list[i] != NULL) {
    //    printf("%s\n", inet_ntoa(*(struct in_addr*)hp->h_addr_list[i]));
    //    ++i;
    //}
    return 0;
}

void handle_sigpipe(int sig)
{
    printf("[sigpipe] recv a sig=%d\n", sig);
}

int main()
{
    //往一个已经关闭的socket写入数据会触发SIGPIPE
    signal(SIGPIPE, handle_sigpipe);

    int sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock < 0) {
        ERR_EXIT("socket fail!");
    }
    
    struct sockaddr_in servaddr;
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(8914);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    if(connect(sock, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
        ERR_EXIT("connect fail!");
    }
    
    struct sockaddr_in localaddr;
    socklen_t addrlen = sizeof(localaddr);
    if(getsockname(sock, (struct sockaddr*)&localaddr, &addrlen) < 0){
        ERR_EXIT("getsockname fail!");
    }
    
    printf("local ip=%s, port=%d\n", inet_ntoa(localaddr.sin_addr), ntohs(localaddr.sin_port));

    PACKET_st recvbuf;
    PACKET_st sendbuf;
    memset(&recvbuf, 0, sizeof(recvbuf));
    memset(&sendbuf, 0, sizeof(sendbuf));

    int i;
    int maxi = 1;
    struct pollfd client[3];
    for(i = 0; i < 3; ++i) {
        client[i].fd = -1;
    }
    
    int nready = 0;
    int fd_stdin = fileno(stdin);
    client[0].fd = fd_stdin;
    client[0].events = POLLIN;
    client[1].fd = sock;
    client[1].events = POLLIN;
    
    while(1){
        nready = poll(client, maxi + 1, -1);
        if(nready == -1) {
            if(errno == EINTR) {
                continue;
            }
            ERR_EXIT("poll");
        }
        
        if(nready == 0) {
            continue;
        }
        
        if(client[0].revents & POLLIN) {
            //printf("stdin ......\n");
            if(fgets(sendbuf.buf, sizeof(sendbuf.buf), stdin) == NULL){
                printf("stdin is null ...\n");
                shutdown(sock, SHUT_WR);
            } else {
                int len = strlen(sendbuf.buf);
                sendbuf.len = htonl(len);
                write(sock, &sendbuf, 4 + len);
                memset(&sendbuf, 0, sizeof(sendbuf));
            }
            
            if(--nready <= 0) {
                continue;
            }
        }
        
        if(client[1].revents & POLLIN) {
            //printf("sock in ......\n");
            int ret = read(sock, &recvbuf.len, 4);
            if(ret == -1) {
                ERR_EXIT("cli read fail!");
            } else if(ret < 4) {
                printf("server close 1.\n");
                break;
            }
            
            int n = ntohl(recvbuf.len);
            ret = read(sock, &recvbuf.buf, n);
            if(ret == -1) {
                ERR_EXIT("cli read fail!");
            } else if(ret < n) {
                printf("server close 2\n");
                break;
            }
            
            printf("recv: len=%d, ctx=%s", ntohl(recvbuf.len), recvbuf.buf);
            //fputs(recvbuf.buf, stdout);
            
            memset(&recvbuf, 0, sizeof(recvbuf));
            
            if(--nready <= 0) {
                continue;
            }
        }
    }
    
    close(sock);
    return 0;
}

编译运行:

[root@QIANZI-BASE keke]# g++ -o pollClient pollClient.cpp

猜你喜欢

转载自blog.csdn.net/qian_feifei/article/details/83005070