现在的位置: 首页 > 综合 > 正文

UNP函数笔记五: 套接字选项

2013年08月30日 ⁄ 综合 ⁄ 共 2632字 ⁄ 字号 评论关闭

第七章  套接字选项:

#include <sys/socket.h>
int getsockopt(int sockfd, int level, int optname, 
               void * optval, socklen_t * optlen);
int setsockopt(int sockfd, int level, int optname, 
               const void * optval, socklen_t optlen);
    success return 0, error return -1
    level = SOL_SOCKET:
        optname:
            SO_DEBUG,     only for TCP
            SO_DONTROUTE, 
            SO_KEEPALIVE, send check seg per 2hours, 
                          may get error: ECONNRESET/ETIMEDOUT/EHOSTUNREACH
            SO_LINGER, 
                struct linger {
                    int  l_onoff;   /* 0=off, nonzero=on */
                    int  l_linger;  /* linger time, as seconds */
                };
                l_onoff is 0:
                     close() no wait to return
                l_onoff is nonzero and l_linger is 0:
                     close() send RST, 
                     no four-connect-stop-orders, 
                     no TIME_WAIT state
                l_onoff is nonzero and l_linger is nonzero:
                     if time out close() return EWOULDBLOCK
            SO_OOBINLINE, 
            SO_RCVBUF, 
            SO_RCVLOWAT, 
            SO_SNDBUF, 
            SO_SNDLOWAT, 
            SO_RCVTIMEO, 
            SO_SNDTIMEO, 
            SO_REUSEADDR, TCP-server should set this socket option
            SO_REUSEPORT, 
            SO_TYPE, 
    level = IPPROTO_TCP:
        optname:
            TCP_MAXSEG, 
            TCP_NODELAY,  forbid TCP-Nagle algorithm (default)

int bind_connect_listen(int sockfd, 
                        const struct sockaddr * laddr, int laddrlen, 
                        const struct sockaddr * faddr, int faddrlen, 
                        int listen);
    better than bind() + (connect()/listen())
    success return 0, error return -1

#include <fcntl.h>
int fcntl(int fd, int cmd, ... /* int arg */ );
    cmd:
        GETFL, SETFL, GETOWN, SETOWN
    error return -1
    cmd = F_SETFL, arg = O_NONBLOCK
    cmd = F_SETFL, arg = O_ASYNC, get SIGIO when io-done

示例:

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netinet/tcp.h> 

int
main(int argc, char * argv[])
{
    int                 sockfd;
    int                 rcvbuf;
    int                 mss;
    socklen_t           len;
    struct sockaddr_in  servaddr;

    if (argc != 2) {
        printf("usage: rcvbuf <IPaddress>\n");
        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        printf("socket error: %s\n", strerror(errno));
        exit(1);
    }

    len = sizeof(rcvbuf);
    if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len) == -1) {
        printf("getsockopt SO_RCVBUF error: %s\n", strerror(errno));
        exit(1);
    }
    len = sizeof(mss);
    if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) == -1) {
        printf("getsockopt TCP_MAXSEG error: %s\n", strerror(errno));
        exit(1);
    }
    printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(13);  /* daytime server */
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) {
        printf("inet_pton error: %s\n", strerror(errno));
        exit(1);
    }

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1) {
        printf("connect error: %s\n", strerror(errno));
        exit(1);
    }

    len = sizeof(rcvbuf);
    if (getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len) == -1) {
        printf("getsockopt SO_RCVBUF error: %s\n", strerror(errno));
        exit(1);
    }
    len = sizeof(mss);
    if (getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len) == -1) {
        printf("getsockopt TCP_MAXSEG error: %s\n", strerror(errno));
        exit(1);
    }
    printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);

    exit(0);
}

抱歉!评论已关闭.