• Linux C 网络编程——3. TCP套接口编程


    1. 基本流程

    TCP协议通讯流程

    2. socket()

    int socket(int domain, int type, int protocol);

    socket()打开一个网络通讯端口,如果成功的话,就像open()一样返回一个文件描述符,应用程序可以像读写文件一样用read/write在网络上收发数据,如果socket()调用出错则返回-1。
    (1)domain:
    AF_INET:IPv4
    AF_INET6: ipv6
    AF_UNIX:非网络环境
    AF_UNSPIC:undefined
    (2)type

    SOCK_STREAM:创建TCP流套接字

    SOCK_DGRAM:创建UDP数据报套接字

    SOCK_RAW:创建原始套接字

    (3)protocol:指定某个协议的特定类型
    参数protocol通常设置为0,表示通过参数domain指定的协议族和参数type指定的套接字类型来确定使用的协议。
    (4)返回值
    执行成功后返回一个新创建的套接字;若有错误发生则返回一个-1,错误代码存入errno中。


    3. bind()

    int bind(int sockfd,struct sockaddr *my_addr,socklen_t addrlen)

    函数bind()的作用是将一个套接字文件描述符与地址和端口绑定。

    (1)sockfd:

    sockfd是调用socket函数返回的文件描述符;

    (2)addrlen

    sockaddr结构的长度。

    (3)my_addr

    一个指向sockaddr结构的指针,它保存着本地套接字的地址(即端口和IP地址)信息。不过由于系统兼容性的问题,一般不使用这个结构,而使用另外一个结构(structsockaddr_in)来代替

    (4)return

    函数成功后返回0,当有错误发生时则返回-1,错误代码存入errno中。


    struct sockaddr_in addr_serv,addr_client;/*本地的地址信息*/
    memset(&serv_addr,0,sizeof(structsockaddr_in));
    addr_serv.sin_family= AF_INET;/*协议族*/
    addr_serv.sin_port= htons(SERV_PORT);/*本地端口号*/
    addr_serv.sin_addr.s_addr= htonl(INADDR_ANY); /*任意本地地址*/
    /*套接字绑定*/
    
    if(bind(sock_fd,(structsockaddr *)&addr_serv),sizeof(struct sockaddr_in)) <0)
    {
           perror(“bind”);
           exit(1);
    }
    

    4. listen()

     

    int listen(int sockfd,int list_size);

    用来初始化服务器可连接队列,服务器处理客户端连接请求的时候是顺序处理的,同一时间仅能处理一个客户端连接。当多个客户端的连接请求同时到来的时候,服务器并不是同时处理,而是将不能处理的客户端连接请求放到等待队列中,这个队列的长度由listen()函数来定义。

    (1)sockfd

    sockfd是调用socket函数返回的文件描述符

    (2)list_size

    指定该连接队列的最大长度。如果连接队列已经达到最大,之后的连接请求被服务器拒绝。大多数系统的设置为20,可以将其设置修改为5或者10,根据系统可承受负载或者应用程序的需求来确定。

    (3)return

    当listen()函数成功运行时,返回值为0;当运行失败时,它的返回值为-1,错误代码存入errno中。

    5. accept()

     

    #include<sys/types.h>

    #include<sys/socket.h>

    int accept(int sock_fd,struct sockaddr*addr,socklen_t *addrlen)

    3次握手完成后,server会调用accept()接受一个链接请求。

    如果在调用此函数之前,没有链接请求就会把进程阻塞,等待链接sock_fd:建立套接字时返回的套接字文件描述符,调用socket()返回的。

    (1)sock_fd

    是由函数socket创建,经函数bind绑定到本地某一端口上,然后通过函数listen转化而来的监听套接字。

    (2)addr

    用来保存客户端的地址和端口。

    注:返回参数

    (3)addrlen

    入:addr缓冲区的大小。

    出:addr 所指向的结构体的大小。

    (4) return

    accept()函数的返回值是新连接的客户端套接字文件描述符,与客户端之间的通信是通过accept()返回的新套接字文件描述符来进行的,而不是通过建立套接字时的文件描述符。如果accept()函数发生错误,accept()会返回-1,通过errno可以得到错误值。

    (5)如果参数sock_fd所指定的套接字被设置为阻塞方式(Linux下的默认方式),且连接请求队列为空,则accept()将被阻塞直到有连接请求到此为止;如果参数s所指定的套接字被设置为非阻塞方式,如果队列为空,accept将立即返回-1,errno被设置为EAGAIN.


    6. connect()

     

     

    #include<sys/types.h>

    #include<sys/socket.h>

    int connect(int sock_fd,struct sockaddr  *serv_addr,socklen_taddrlen);

    TCP:则connect()函数用于服务器发出连接请求,服务器的IP地址和端口号由 参数serv_addr指定。

    UDP:则connect函数并不建立真正的连接,它只是告诉内核与该套接字进行通信的目的地址(由第二个参数指定),只有该目的地址发来的数据才会被该socket接收。调用connect函数的好处是不必在每次发送和接收数据时都指定目的地址。

    (1)serv_addr

    是一个指向数据结构sockaddr的指针,其中包括客户端需要连接的服务器的目的IP地址和端口号。

    (2)addrlen

    表示了第二了参数的大小,可以使用sizeof(struct sockaddr)

    (3)return

    执行成功后返回0,有错误发生则返回-1,错误代码存入errno中。


    7. send()

     

     

    #include<sys/types.h>

    #include<sys/socket.h>

    ssize_t send(int conn_fd,const void *buf,size_t len, int flags);

    函数send用来在TCP套接字上发送数据,send只能对处于连接状态的套接字使用。

    (1)conn_fd

    为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符。

    (2)buf

    存放发送数据的缓冲区。

    (3)len

    发送缓冲区的长度

    (4)flags

    为控制选项,一般设置为0,或取以下值:

    • MSG_OOB:在指定的套接字上发送带外数据(out-of-band data),该类型的套接字必须支持带外数据(如:SOCK_STREAM).

    • MSG_DONTROUTE:通过最直接的路径发送数据,而忽略下层协议的路由设置。

     

    (5)return

    执行成功返回实际发送数据的字节数,出错则返回-1,错误代码存入errno中。

    执行成功只是说明数据写入套接字的缓冲区中,并不表示数据已经成功地通过网络发送到目的地。


    8. recv() 接收数据

     

     

    #include<sys/types.h>

    #include<sys/socket.h>

    ssize_t recv(int conn_fd,void *buf,size_t len,int flags)

    recv()用来TCP套接字上接收数据。函数recv从指定的套接字描述符上接收数据并保存到指定buf中

    (1)conn_fd

    为已建立好连接的套接字描述符,即调用accept()函数后返回的套接字描述符

    (2)buf

    接收缓冲区

    (3)len

    接收缓冲区的大小

    (4)flags

    为控制选项,一般设置为0或取以下数值

    • MSG_OOB:请求接收带外数据

    • MSG_PEEK:只查看数据而不读出

    • MSG_WAITALL:只在接收缓冲区满时才返回。

     

    (5)return

    函数执行成功返回接收到的数据字节数,出错返回-1,错误代码存入errno中。



  • 相关阅读:
    康托展开
    Linux Command Line Basics
    hihoCoder 1401 Registration
    C++ 参考网站
    Linux 下的常用工具
    SQL 命令
    GNU MAKE 笔记
    一道基本的计算几何题
    uva 1451 平均值
    bzoj 1826 缓存交换
  • 原文地址:https://www.cnblogs.com/riskyer/p/3398175.html
Copyright © 2020-2023  润新知