• 套接字编程常用函数


    基本TCP套接字编程

    socket函数

    这是一个进程在执行网络I/O之前必须调用的函数,用于指定期望的通信协议类型

    #include <sys/socket.h>
    
    int socket(int family, int type, int protocol);   // 调用成功返回非负的套接字描述符,出错返回-1

    connect函数

    TCP客户端用connect函数来建立与TCP服务器的连接

    #include <sys/socket.h>
    
    int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);   // 调用成功返回0,出错返回-1

    bind函数

    bind函数用于将一个本地协议地址赋予一个套接字

    #include <sys/socket.h>
    
    int bind(int sockfd, const struct sockaddr *myaddr, socklen_t addrlen);   // 调用成功返回0,出错返回-1

    listen函数

    listen函数仅由TCP服务器调用,listen函数将一个未连接的套接字转换成一个被动套接字,指
    示内核应接受指向该套接字的连接请求。除此之外, listen函数规定了内核应该为相应套接字
    排队的最大连接个数(backlog = 未完成连接队列 + 已完成连接队列, 内核允许在这个套接字
    上排队的最大客户连接数)。

    #include <sys/socket.h>
    
    int listen(int sockfd, int backlog);   // 调用成功返回0,出错返回-1

    accept函数

    accept函数由TCP服务器调用,用于从已完成连接队列头返回下一个已完成连接

    #include <sys/socket.h>
    
    // cliaddr、addrlen用于返回已连接对端进程(客户)的协议地址
    // 调用成功返回非负描述符,出错返回-1
    int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);  

    close函数

    close函数可用于关闭套接字,并终止TCP连接

    #include <unistd.h>
    
    int close(int sockfd);     // 调用成功返回0,出错返回-1

    getsockname函数和getpeername函数

    这两个函数用于返回与某个套接字关联的本地协议地址(getsockname),或者返回与某个套接字
    关联的外地协议地址(getpeername)

    #include <sys/socket.h>
    
    int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t *addrlen);   // 调用成功返回0,出错返回-1
    
    int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t *addrlen);    // 调用成功返回0,出错返回-1

    用于获取个设置套接字选项

    #include <sys/socket.h>
    
    // 调用成功返回0,出错返回-1
    int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);       
    
    // 调用成功返回0,出错返回-1
    int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);   

    示例:简单的时间获取程序————客户端和服务端实现

     1 #include "net.h"
     2 
     3 #define SA struct sockaddr
     4 
     5 int main(int argc, char **argv)
     6 {
     7     int sockfd, n;
     8     char recvline[MAXLINE + 1];
     9     struct sockaddr_in servaddr;
    10 
    11     if (argc != 2)
    12     {
    13         printf("Error: Options!
    ");
    14           return -1;
    15     }
    16 
    17     if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    18     {
    19         printf("Error: Socket!
    ");
    20           return -1;
    21     }
    22 
    23     bzero(&servaddr, sizeof(servaddr));
    24     servaddr.sin_family = AF_INET;
    25     servaddr.sin_port = htons(13);
    26 
    27     if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
    28     {
    29         printf("Error: inet_pton for %s
    ", argv[1]);
    30                 return -1;
    31     }
    32 
    33     if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
    34     {
    35         printf("Error: Connect!
    ");
    36     }
    37 
    38     while ( (n = read(sockfd, recvline, MAXLINE)) > 0 )
    39     {
    40         recvline[n] = '';   
    41 
    42               if (fputs(recvline, stdout) == EOF)
    43               {
    44                         printf("Error: Fputs!
    ");
    45               }
    46     }
    47 
    48     if (n < 0)
    49     {
    50         printf("Erroe: Read!
    ");
    51     }
    52 
    53     return 0;
    54 }
     1 #include "net.h"
     2 
     3 #define SA struct sockaddr
     4 
     5 int main(int argc, char **argv)
     6 {
     7     int listenfd, connfd;
     8     struct sockaddr_in servaddr;
     9     char buff[MAXLINE];
    10     time_t ticks;
    11 
    12     if ( (listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
    13     {
    14         printf("Error: Socket!
    ");
    15                 return -1;
    16     }
    17 
    18     bzero(&servaddr, sizeof(servaddr));
    19     servaddr.sin_family = AF_INET;
    20     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    21     servaddr.sin_port = htons(13);
    22 
    23     if (bind(listenfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
    24     {
    25         printf("Error: Bind!
    ");
    26                 return -1;
    27     }
    28 
    29     if (listen(listenfd, LISTENQ) < 0)
    30     {
    31         printf("Error: Listen!
    ");
    32                 return -1;
    33     }
    34 
    35     for ( ; ; )
    36     {
    37         if ( (connfd = accept(listenfd, (SA *) NULL, NULL)) < 0 )
    38         {
    39             printf("Error: Accept!
    ");
    40             return -1;
    41         }
    42 
    43                 ticks = time(NULL);
    44                 snprintf(buff, sizeof(buff), "%.24s
    ", ctime(&ticks));
    45 
    46                 if (write(connfd, buff, strlen(buff)) < 0)
    47                 {
    48                     printf("Error: Write!
    ");
    49                     return -1;
    50                 }
    51 
    52                 if (close(connfd) < 0)
    53                 {
    54                     printf("Error: Close!
    ");
    55                     return -1;
    56                 }
    57     }
    58 
    59     return 0;
    60 }

     基本UDP套接字编程

    recvfrom和sendto函数

    类似于标准的read和write函数

    #include <sys/socket.h>
    
    // 从套接字sockfd的接受缓冲区中读取nbytes字节的数据写入到指针buff所指向的位置
    // 将发送此数据的对端的协议地址用from返回
    ssize_t recvfrom(int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *from, socklen_t *addrlen);
    
    // 将指针buff指向的位置存放的nbytes字节的数据发送到协议地址为to的对端
    ssize_t sendto(int sockfd, void *buff, size_t nbytes, int flags, struct sockaddr *to, socklen_t *addrlen);
    
    // 上述两个函数调用成功时返回读或写的字节数,出错返回-1
  • 相关阅读:
    Linux基础命令---sudo
    Linux基础命令---yes
    Linux基础命令---shutdown
    Divide Two Integers
    java 判断两个数是否异号
    字节顺序的详细解释(转)
    java无符号移位(>>>)和有符号移位(>>)
    java 参数化类型
    c++事件内核对象(event)进程间激活(转)
    windows多线程编程(一)(转)
  • 原文地址:https://www.cnblogs.com/lnlin/p/9381339.html
Copyright © 2020-2023  润新知