UNP函数笔记二: 基本TCP套接字编程

58 篇文章 0 订阅
49 篇文章 0 订阅

第四章  基本TCP套接字编程:

#include <sys/socket.h>
int socket(int family, int type, int protocol);
    family:
        AF_INET, AF_INET6, AF_LOCAL(AF_UNIX), AF_ROUTE, AF_KEY
    type:
        SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET, SOCK_RAW
    protocol:
        IPPROTO_TCP, IPPROTO_UDP, IPPROTO_SCTP, 0(default)
    error return -1

#include <sys/socket.h>
int connect(int sockfd, const struct sockaddr * servaddr, socklen_t addrlen);
    success return 0, error return -1

#include <sys/socket.h>
int bind(int sockfd, const struct sockaddr * myaddr, socklen_t addrlen);
    success return 0, error return -1
    server:
        IPV4:
            struct sockaddr_in servaddr;
            servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        IPV6:
            struct sockaddr_in6 servaddr;
            servaddr.sin6_addr = in6addr_any;

#include <sys/socket.h>
int listen(int sockfd, int backlog);
    success return 0, error return -1
    convert active-socket to passive-socket

#include <sys/socket.h>
int accept(int sockfd, struct sockaddr * cliaddr, socklen_t * addrlen);
    error return -1
    sockfd should be a passive-socket(listened-socket)

#include <unistd.h>
pid_t fork(void);
    error return -1

#include <unistd.h>
int execl(const char * pathname, const char * arg0, ... /* (char *)0 */);
int execv(const char * pathname, char * const argv[]);
int execle(const char * pathname, const char * arg0, ... 
           /* (char *)0, char * const envp[] */);
int execve(const char * pathname, char * const argv[], char * const envp[]);
int execlp(const char * filename, const char * arg0, ... /* (char *)0 */);
int execvp(const char * filename, char * const argv[]);
    success no return, error return -1

#include <unistd.h>
int close(int sockfd);
    success return 0, error return -1

#include <sys/socket.h>
int getsockname(int sockfd, struct sockaddr * localaddr, socklen_t * addrlen);
int getpeername(int sockfd, struct sockaddr * peeraddr, socklen_t * addrlen);
    success return 0, error return -1

示例:

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

void 
Listen(int fd, int backlog)
{
    char * ptr;

    /* can override 2nd argument with environment variable */
    if ((ptr = getenv("LISTENQ")) != NULL) {
        backlog = atoi(ptr);
    }

    if (listen(fd, backlog) < 0) {
        printf("listen error %s\n", strerror(errno));
        exit(1);
    }
}

#include <time.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define LISTENQ 5
#define MAXLINE 1024

int
main(int argc, char **argv)
{
    int	                listenfd;
    int                 connfd;
    socklen_t           len;
    struct sockaddr_in  servaddr;
    struct sockaddr_in  cliaddr;
    char                buff[MAXLINE];
    time_t              ticks;

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

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port        = htons(13);  /* daytime server */

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

    if (listen(listenfd, LISTENQ) == -1) {
        printf("listen error\n");
        exit(1);
    }

    for ( ; ; ) {
        len = sizeof(cliaddr);
        connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &len);
        if (connfd == -1) {
            printf("accept error %s\n", strerror(errno));
            exit(1);
        }
        if (inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)) == NULL) {
            printf("inet_ntop error %s\n", strerror(errno));
            exit(1);
        }
        printf("connection from %s, port %d\n", buff, ntohs(cliaddr.sin_port));

        ticks = time(NULL);
        snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks));
        len = strlen(buff);
        if (write(connfd, buff, len) != len) {
            printf("write error %s\n", strerror(errno));
            exit(1);
        }
        if (close(connfd) == -1) {
            printf("close error %s\n", strerror(errno));
            exit(1);
        }
    }
}

#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <arpa/inet.h>
#include <sys/socket.h>

#define MAXLINE  1024

int
main(int argc, char **argv)
{
    int                 sockfd;
    int                 n;
    char                recvline[MAXLINE + 1];
    struct sockaddr_in  servaddr;

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

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

    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 for %s: %s\n", argv[1], strerror(errno));
        exit(1);
    }

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

    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;  /* null terminate */
        if (fputs(recvline, stdout) == EOF) {
            printf("fputs error %s\n", strerror(errno));
            exit(1);
        }
    }
    if (n < 0) {
        printf("read error\n %s\n", strerror(errno));
        exit(1);
    }

    exit(0);
}

#include <sys/socket.h>

int 
sockfd_to_family(int sockfd)
{
    struct sockaddr_storage ss;
    socklen_t  len;

    len = sizeof(ss);
    if (getsockname(sockfd, (struct sockaddr *)&ss, &len) < 0) {
        return(-1);
    }
    return(ss.ss_family);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值