• linux c 笔记 网络编程(三)..套接字数据传输


    TCP套接字的数据传输

    1.传送数据
    函数seed用来在TCP套接字上发送数据,函数原型
    #include <sys/socket.h>
    #include <sys/types.h>
    ssize_t send( int s, const void *msg ,size_t len ,int flags);
    函数send只能对处于连接状态的套接字使用,参数s为已建立好连接的套接字描述符,即accept的返回值。
    参数msg指向存放待发送数据的缓冲区
    参数len为待发数据的长度
    参数flag为控制选项,

    #define BUFFERSIZI    1500
    char  send_buf[BUFFERSIZI]

    if (send (conn_fd, send_buf , len ,0) < 0)
    {
        perror("send");
        exit(1);
    }

    2.接受数据:
    函数recv用来在TCP套接字上接受数据:
    #include <sys/socket.h>
    #include <sys/types.h>
    ssize_t recv(int s, void *buf, size_t len ,int flags);

    函数recv从参数s所指定的套接字描述符上接收数据并保存到参数buf所指定的缓冲区,参数len则为缓冲区长度
    常见用法
    char     recv_buf[BUFFERSIZE];
    ...
    if ( recv(conn_fd ,recv_buf , sizeof (recv_buf ) ,0 ) < 0 ) {
        perror("recv");
        exit(1);
    }


    UDP套接字的数据传输
    1.发送数据:
    函数sendto用来在UDP套接字上发送数据
    #include <sys/socket.h>
    #include <sys/types.h>
    ssize_t sendto(int s,const void *msg,size_t len,int flags,const struct sockaddr *to,socklen_t tolen);
    const struct sockaddr *to ;
    函数功能与函数send类似,但函数sendto不需要套接字处于连接状态,所以该函数通常用来发送UDP数据,同时因为是无连接的套接字,在使用sendto时需要指定数据的目的地址,参数msg指向待发送数据的缓冲区。
    参数len指定了待发送数据的长度
    参数flags是控制选项,含义与send函数中的一致
    参数to用于指定目的地址,目的地址的长度由tolen指定
    该函数常见的用法
    char    seed_buf[BUFFERSIZE];
    struct sockaddr_in    dest_addr;

    //设置目的地址
    memset(&dest_addr ,0 , sizeof(struct sockaddr_in ));
    dest_addr.sin_family = AF_INET;
    dest_addr.sin_port = htons(DEST_PORT);

    if(inet_aton("172.17.242.131",&dest_addr.sin_addr ) < 0) {
        perror("inet_aton");
        exit(1);
    }

    if(sendto(sock_fd ,send_buf , len ,0 ,(struct sockaddr *)&dest_addr ,sizeof(struct sockaddr_in) ) < 0) {
        perror("sento ");
        exit(1);
    }


    2.接受数据:recvfrom
    数据的发送和接受:
    函数recvfrom用来在UDP套接字上接受数据,函数原型:
    #include <sys/socket.h>
    #include <sys/types.h>
    ssize_t recvfrom(int s ,void *buf,size_t len,int flags,struct sockaddr *from,socklen_t *fromlen);
    与函数recv功能类似,只是函数recv只能用于面向连接的套接字,而函数recvfrom没有此限制,可以用于从无连接的套接字上接收数据
    参数buf指向接收缓冲区
    参数len指定了缓冲区的大小
    参数flags是控制选项,含义与recv中的一致
    如果参数from非空,且该套接字不是面向连接的,则函数recvfrom返回时,参数from中将保存数据的源地址
    参数fromlen在调用recvfrom前为参数from的长度,调用recvfrom后将保存from的实际大小
    套接字为阻塞方式下该函数的常见用法
    char recv_buf[BUFFERSIZE];
    struct sockaddr_in src_addr;
    int src_len;

    src_len = sizeof(struct sockaddr_in);
    if(recvfrom (sock_fd ,recv_buf , sizeof(recv_buf ) ,0  ,(struct sockaddr *)&src_addr ,&src_len ) < 0) {
        perror("again_recvfrom");
        exit(1);
    }


    关闭套接字:
    #include <unistd.h>
    int  close(int fd );
    fd 为一个套接字的描述符,请函数关闭一个套接字
    执行成功返回0,出错返回-1,错误代码存入errno中

    #include <sys/socket.h>
    int shutdown (int s ,int how);

    用来关闭一个套接字描述符,与关闭文件描述符是类似的
    它允许对套接字进行单向关闭或者全部关闭,参数s为待关闭的套接字
    参数 how 指定了关闭方式,具体取值如下:  
    SHUT_RD : 将连接上的读通道关闭,此后进程将不能再接收到任何数据,接收缓冲区中还未被读取的数据也将被丢弃,但仍然可以在该套接字上发送数据。  
    SHUT_WR : 将连接上的写通道关闭,此后进程将不能再发送任何数据,发送缓冲区中还未被发送的数据也将被丢弃,但仍然可以在该套接字上接收数据。  
    SHUT_RDWR : 读、写通道都将被关闭。  
    执行成功返回 0,出错则返回 -1,错误代码存入 errno 中。

    下面摘用网上的一段话来说明二者的区别:
    close-----关闭本进程的socket id,但链接还是开着的,用这个socket id的其它进程还能用这个链接,能读或写这个socket id
    shutdown--则破坏了socket 链接,读的时候可能侦探到EOF结束符,写的时候可能会收到一个SIGPIPE信号,这个信号可能直到

  • 相关阅读:
    【每天一道PAT】1001 A+B Format
    C++ STL总结
    开篇
    happen-before原则
    java多线程的状态转换以及基本操作
    集合初始容量
    fail-fast机制
    Stack
    Iterator
    Vector
  • 原文地址:https://www.cnblogs.com/kaylee-lr/p/4701948.html
Copyright © 2020-2023  润新知