socketpair函数声明

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. int socketpair(int d, int type, int protocol, int sv[2]);

socketpair()函数用于创建一对无名的、相互连接的套接子。
如果函数成功,则返回0,创建好的套接字分别是sv[0]和sv[1];否则返回-1,错误码保存于errno中。
基本用法:
1. 这对套接字可以用于全双工通信,每一个套接字既可以读也可以写。例如,可以往sv[0]中写,从sv[1]中读;或者从sv[1]中写,从sv[0]中读;
2. 如果往一个套接字(如sv[0])中写入后,再从该套接字读时会阻塞,只能在另一个套接字中(sv[1])上读成功;
3. 读、写操作可以位于同一个进程,也可以分别位于不同的进程,如父子进程。如果是父子进程时,一般会功能分离,一个进程用来读,一个用来写。因为文件描述副sv[0]和sv[1]是进程共享的,所以读的进程要关闭写描述符, 反之,写的进程关闭读描述符。

sendmsg函数

定义函数
int sendmsg(int s, const strcut msghdr *msg, unsigned int flags);
函数说明:sendmsg()用来将数据由指定的socket传给对方主机.
参数s:为已建立好连线的socket, 如果利用UDP协议则不需经过连线操作.
参数msg:指向欲连线的数据结构内容, 参数flags 一般默认为0, 详细描述请参考send().
返回值:成功返回发送的字节数,出错返回-1
msghdr结构如下:

  1. struct msghdr
  2. {
  3. void *msg_name; //发送或接收数据的地址
  4. socklen_t msg_namelen; //地址长度
  5. strcut iovec * msg_iov; //要发送或接受数据
  6. size_t msg_iovlen; //容器数据长度
  7. void * msg_control; //附属数据
  8. size_t msg_controllen; //附属数据长度
  9. int msg_flags; //接收消息的标志
  10. };
  11. struct iovec {
  12. void * iov_base; /* [XSI] Base address of I/O memory region */
  13. size_t iov_len; /* [XSI] Size of region iov_base points to */
  14. };

recvmsg函数

定义函数
int recvmsg(int s, struct msghdr *msg, unsigned int flags);
函数说明:recvmsg()用来接收远程主机经指定的socket 传来的数据.
参数s 为已建立好连线的socket, 如果利用UDP 协议则不需经过连线操作.
参数msg 指向欲连线的数据结构内容,
参数flags 一般设0, 详细描述请参考send().
返回值:成功则返回接收到的字符数, 失败则返回-1, 错误原因存于errno 中.

send函数

定义函数:int send(int s, const void * msg, int len, unsigned int falgs);
函数说明:send()用来将数据由指定的socket 传给对方主机.
参数s 为已建立好连接的socket.
参数msg 指向欲连线的数据内容.
参数len 则为数据长度.
参数flags 一般设0, 其他数值定义如下:
MSG_OOB 传送的数据以out-of-band 送出.
MSG_DONTROUTE 取消路由表查询
MSG_DONTWAIT 设置为不可阻断运作
MSG_NOSIGNAL 此动作不愿被SIGPIPE 信号中断.
返回值:成功则返回实际传送出去的字符数, 失败返回-1. 错误原因存于errno.

示例:

创建两个进程,子进程发送数据,父进程接收数据。

  1. #include <sys/types.h>
  2. #include <sys/socket.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <unistd.h>
  6. #include <errno.h>
  7. #include <string.h>
  8. int main(int arc, char *argv[])
  9. {
  10. int ret;
  11. int sockfd[2];
  12. pid_t pid;
  13. struct msghdr msg; //发送消息
  14. struct iovec iov[1];
  15. char send_buf[100] = "this is a test!";
  16. struct msghdr msgr; //接收消息
  17. struct iovec iovr[1];
  18. char recv_buf[100];
  19. //创建套接字对
  20. /*
  21. int socketpair(int d, int type, int protocol, int sv[2]);
  22. */
  23. ret = socketpair(AF_UNIX, SOCK_STREAM, 0, sockfd);
  24. if (ret == -1)
  25. {
  26. printf("socketpair error!\n");
  27. return 1;
  28. }
  29. pid = fork();
  30. switch (pid)
  31. {
  32. case -1:
  33. printf("fork error!\n");
  34. break;
  35. case 0:
  36. close(sockfd[0]);
  37. /* sock[0]发送数据*/
  38. bzero(&msg, sizeof(msghdr));
  39. msg.msg_name = NULL;
  40. msg.msg_namelen = 0;
  41. iov[0].iov_base = send_buf;
  42. iov[0].iov_len = sizeof(send_buf);
  43. msg.msg_iov = iov;
  44. msg.msg_iovlen = 1;
  45. printf("begin to send data...\n");
  46. printf("the data to be send is %s \n", send_buf);
  47. ret = sendmsg(sockfd[1], &msg, 0);
  48. if (ret == -1)
  49. {
  50. printf("sendmsg error!\n");
  51. return -1;
  52. }
  53. printf("send success!\n");
  54. break;
  55. default:
  56. sleep(1);
  57. close(sockfd[1]);
  58. /* sock[1]发送数据*/
  59. bzero(&msgr, sizeof(msghdr));
  60. msgr.msg_name = NULL;
  61. msgr.msg_namelen = 0;
  62. iovr[0].iov_base = recv_buf; //接收的数据放到这里
  63. iovr[0].iov_len = sizeof(recv_buf);
  64. msgr.msg_iov = iovr;
  65. msgr.msg_iovlen = 1;
  66. printf("begin to receive data...\n");
  67. ret = recvmsg(sockfd[0], &msgr, 0);
  68. if (ret == -1)
  69. {
  70. printf("receive message error!\n");
  71. return -1;
  72. }
  73. printf("received data is [%s] \n", recv_buf);
  74. break;
  75. }
  76. for (; ;)
  77. {
  78. sleep(1);
  79. }
  80. return 0;
  81. }