send函数:
  #include <sys/types.h>
  #include <sys/socket.h>
  ssize_t send(int s,const void*buf,size_t len,int flags);
  send函数将缓冲区buf中的大小为len的数据,通过套接字文件描述符s按照flasg指定的方式发生出去(其中的含义与recv()中一致),它的返回值是成功发生的字节数。
  由于用户缓冲区buf中的数据通过send发送,不一定能够全部发送出去,所以要检查send()返回值。当send()的返回值小于len时,表面缓冲区中仍有部分数据没有发送成功,这时需要重新发送剩余部分的数据。通常的剩余数据发送方式是对原来的buf中的数据位置进行偏移,偏移的大小为已经发送成功的字节数。
  当send()返回-1时,错误了。

  函数send()只能用于套接字处于连接状态的描述符,之前必须用connect()函数或者其他函数进行连接。对于send和write之间的差别是表示发送方式flag,当flag为0时,send()和write()完全一样的,且send(s,buf,len,flags)和sendto(s,buf,len,flags,NULL,0)是等价的。
  readv函数:
  #include <sys/uio.h>
  ssize_t readv(int s,const struct iovec*vector,int count);
  read()可以接收多个缓冲区的数据。readv函数从套接字描述符s中读取count块的数据放在缓冲区向量vector中。返回值为成功接收到的数据的字节数,当-1时,错误发生。
  其中的参数vector为一个向量的指针,结构struct iover在文件<sys/uio.h>定义:
  1 struct iovec
  2 {
  3     void*iov_base;                             // 向量的缓冲区地址
  4     size_t iov_len;                             // 大小,字节为单位
  5 }

  在调用readv的时候必须指定iovec的iov_len长度,将值放在iov_len中。参数vector指向一块结构vector的内存,大小count定。如下图,其中阴影部分是需要设置的。

  writev函数:
  #include <sys/uio.h>
  ssize_t writev(int s,const struct iovec*vector,int count);
  //// 是不是觉得和readv一样
  总结:
  下表总结了各个函数的区别、特点:O标记的为具备此种属性