socket api常用整理

#include "msocket.h"
#include <sys/param.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/poll.h>
#include <fcntl.h>
#include <sys/sendfile.h>
#include <sys/epoll.h>
#include <sys/un.h>
#include <errno.h>
#include<unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <netinet/in.h>

const int DEF_SOCK_SNDBUF_SIZE = 1000;

void setup_socket_options(int s)
{
    int sndbuf, err;
    socklen_t sz;

    sndbuf = DEF_SOCK_SNDBUF_SIZE;
    err = setsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, 4);
    if (err) {
        ERRMSG("Failed to set SO_SNDBUF to %d.\n", sndbuf);
    }

    sndbuf = 0;
    sz = 4;
    err = getsockopt(s, SOL_SOCKET, SO_SNDBUF, &sndbuf, &sz);
    if (err) {
        DEBMSG("Failed to get SO_SNDBUF.\n");
    }

    DEBMSG("Send buffer size is %d.\n", sndbuf);

    sndbuf = DEF_SOCK_SNDBUF_SIZE;
    err = setsockopt(s, SOL_SOCKET, SO_RCVBUF, &sndbuf, 4);
    if (err) {
        ERRMSG("Failed to set SO_RCVBUF to %d.\n", sndbuf);
    }

    sndbuf = 0;
    sz = 4;
    err = getsockopt(s, SOL_SOCKET, SO_RCVBUF, &sndbuf, &sz);
    if (err) {
        DEBMSG("Failed to get SO_RCVBUF.\n");
    }

    DEBMSG("Recv buffer size is %d.\n", sndbuf);
}


int sock_connect(const char *reip, int port)
{
    int sockfd;
    struct sockaddr_in serv_addr;

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        ERRMSG("opening socket error! \n");
        return NULL;
    }

    bzero(&serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);
    serv_addr.sin_addr.s_addr = inet_addr(reip);
    if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
    {
        ERRMSG("connecting error! \n");
        close(sockfd);
        return -1;
    }

    return sockfd;
}

int tcp_server_init(const char *addr, unsigned short port, int backlog)
{
    int s, on;
    struct sockaddr_in sa;

    struct hostent  h_he;
    struct hostent* h_res = NULL;
    char   h_buff[1024] = {0};
    int    h_err;

    if (NULL == addr) {
        DEBMSG("%s: Bind address cannot be NULL.\n", __func__);
        return -1;
    }

    if (0 != gethostbyname_r (addr, &h_he, h_buff, sizeof(h_buff), &h_res, &h_err)) {
        DEBMSG("%s: Failed to get address of %s.\n", __func__, addr);
        return -1;
    }

    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (s == -1) {
        DEBMSG("%s: Failed to create server socket", __func__);
        return -1;
    }
    fcntl(s, F_SETFL, O_NONBLOCK);

    memcpy(&(sa.sin_addr.s_addr),h_he.h_addr_list[0], 4);
    sa.sin_port = htons(port);
    sa.sin_family = AF_INET;

    int ret = setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &on, 4);
    DEBMSG("-0-%d,%d.\n", ret, on);
    ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, 4);
    DEBMSG("-1-%d,%d.\n", ret, on);

    socklen_t xxx;
    ret = getsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, &xxx);
    DEBMSG("-2-%d,%d.\n", ret, xxx);

    if (bind(s, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) == -1) {
        DEBMSG("%s: Failed to bind to %s", __func__, addr);
        close(s);
        return -1;
    }

    if (listen(s, backlog)) {
        DEBMSG("%s: Failed to make socket listening at %s", __func__, addr);
        close(s);
        return -1;
    }

    setup_socket_options(s);
    return s;
}

int epoll_setup_sock(int epoll_ctlfd, int s, int e)
{
    struct epoll_event event;

    memset(&event, 0, sizeof(event));
    event.events = e; //EPOLLIN /*| EPOLLET*/;
    event.data.fd = s;

    int err = epoll_ctl(epoll_ctlfd, EPOLL_CTL_ADD, s, &event);
    if (err < 0) {
        ERRMSG("Failed to perform control ADD operation: fd=%d, events=%08x", s, event.events);
        return err;
    }

    return 0;
}

int epoll_accept_tcpclient(int s)
{
    int cs;
    struct sockaddr_in csa;
    socklen_t addrlen = sizeof(struct sockaddr_in);
    memset(&csa, 0, sizeof(csa));

    if ((cs = accept(s, (struct sockaddr *)&csa, &addrlen)) == -1) {
        DEBMSG("Failed to accept client");
        return -1;
    }
    fcntl(cs, F_SETFL, O_NONBLOCK);

    setup_socket_options(cs);
    return cs;
}

int set_socket_nonblock(int sockfd)
{
    if (fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFD, 0)|O_NONBLOCK) == -1) {
        return -1;
    }

    int  on;
    int ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &on, 4);
    //DEBMSG("-0-%d,%d.\n", ret, on);
    ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, 4);

    ret = ret;
    //DEBMSG("-1-%d,%d.\n", ret, on);
    return 0;
}

long sock_read(int fd, char *buf, size_t count)
{
    ssize_t L = 0;
    ssize_t R = 0;

    while (L < (ssize_t)count)
    {
        R = read (fd, buf + L, count-L);
        if (R < 0)
        {
            if (EAGAIN == errno || EINTR == errno)
            {
                usleep(20 * 1000);
                continue;
            }
            break;
        }
        else if (R == 0)
        {
            ERRMSG("nonblock read. fd:%d, %s,%d\n", fd, strerror(errno), errno);
            return -1;
        }
        L += R;
    }

    return L;
}

long sock_write (int fd, char *buf, size_t count)
{
    ssize_t L = 0;
    ssize_t R = 0;

    while(L < (ssize_t)count)
    {
        R = write (fd, buf + L, count-L);
        if (R < 0)
        {
            if (EAGAIN == errno || EINTR == errno)
            {
                usleep(20 * 1000);
                continue;
            }

            break;
        }
        else if (R == 0)
        {
            ERRMSG("sock_write: %d, %s,%d\n", R, strerror(errno), errno);
            return -1;
        }
        L += R;
    }

    return L;
}

/**
 * 针对非阻塞FD,尽力读完数据.返回实际读的数据长度
 * return:
 * -1: error.
 * 0: timeout.
 * >0: read data length.
**/
long sock_read_timeout(int sockfd, char *buf, size_t count, int timeout)
{
    ssize_t L = 0;
    ssize_t R = 0;

    while (L < (ssize_t)count)
    {
        struct pollfd rcvpfd = {sockfd,  POLLIN, 0 };
        int ret = poll(&rcvpfd, 1, timeout); //1s
        //ERRMSG("sock_read_timeout: %d, %d\n", sockfd, ret);
        if (ret < 0)
        {
            if (EAGAIN == errno || EINTR == errno)
            {
                usleep(20 * 1000);
                continue;
            }
            return -1;
        }
        else if (ret == 0)
        {//timeout..
            return 0;
        }

        R = read (sockfd, buf + L, count-L);
        if (R < 0)
        {
            if (EAGAIN == errno || EINTR == errno)
            {
                usleep(20 * 1000);
                continue;
            }
            break;
        }
        else if (R == 0)
        {
            ERRMSG("nonblock read. fd:%d, %s,%d\n", sockfd, strerror(errno), errno);
            return -1;
        }
        L += R;
    }

    return L;
}

long sock_write_timeout (int sockfd, char *buf, size_t count, int timeout)
{
    ssize_t L = 0;
    ssize_t R = 0;

    while(L < (ssize_t)count)
    {
        //struct pollfd rcvpfd = { .fd = sockfd, .events = POLLIN, .revents = 0 };
        struct pollfd rcvpfd = {sockfd,  POLLOUT, 0 };
        int ret = poll(&rcvpfd, 1, timeout); //1s
        if (ret < 0) {
            break;
        }

        if (ret == 0) {
            continue;
        }

        R = write (sockfd, buf + L, count-L);
        if (R < 0)
        {
            if (EAGAIN == errno || EINTR == errno)
            {
                usleep(20 * 1000);
                continue;
            }
            break;
        }
        else if (R == 0)
        {
            ERRMSG("sock_write closed: %d, %s,%d\n", sockfd, strerror(errno), errno);
            return -1;
        }

        L += R;
    }

    return L;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值