spice测试工程
来源:互联网 发布:国外数据库 编辑:程序博客网 时间:2024/06/06 19:54
test-stream.c
参考:linux文件描述符传递
http://blog.csdn.net/sparkliang/article/details/5486069
http://blog.csdn.net/sparkliang/article/details/5490242
spice-server
版本:spice-0.14.0
测试工程:test-stream.c
struct RedsStream { int socket; SpiceWatch *watch; RedsStreamPrivate *priv;};
int main(int argc, char *argv[]){ RedsStream *st[2];//结构体定义 int sv[2]; int ret, fd = -1; char c; //spice定义的断言 spice_return_val_if_fail(server_init() == 0, -1); //创建socketpair:create a pair of connected sockets if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) { spice_error("socketpair failed %s", strerror(errno)); return -1; } //创建两个RedsStream 结构体 st[0] = reds_stream_new(server, sv[0]); spice_assert(reds_stream_is_plain_unix(st[0])); st[1] = reds_stream_new(server, sv[1]); spice_assert(reds_stream_is_plain_unix(st[1])); /* send stdin, for the fun of it */ ret = reds_stream_send_msgfd(st[0], 0); //关键函数:发送 spice_assert(ret == 1); //sendmsg系统调用返回值为1,为发送的一个字节 ret = sock_fd_read(sv[1], &c, 1, &fd);//关键函数:接收 spice_assert(c == '@'); //断言是否为接收的数据‘@’ spice_assert(ret == 1); //recvmsg系统调用返回值为1,位接收一个字节 spice_assert(fd != -1); //reds_stream_send_msgfd函数将文件描述符"0",也就是标准输入传给了Redstream st[1],也就是传入的fd。 close(fd); //将fd,就是标准输入关闭 本进程的。 每一个进程默认都有标准输入,标准输出, 标准错误输出 /* send invalid fd behaviour */ //此时fd等于0,参考下面的关键函数。 走另一条路径sendmsg/read 上面的收发是sendmsg/recvmsg ret = reds_stream_send_msgfd(st[0], -1); spice_assert(ret == 1); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd == -1); /* batch test */ //模拟发送一批。但是只发送了两次 ret = reds_stream_send_msgfd(st[0], 0); spice_assert(ret == 1); ret = reds_stream_send_msgfd(st[0], 0); spice_assert(ret == 1); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd != -1); close(fd); ret = sock_fd_read(sv[1], &c, 1, &fd); spice_assert(c == '@'); spice_assert(ret == 1); spice_assert(fd != -1); close(fd); reds_stream_free(st[0]); reds_stream_free(st[1]); return 0;}
//核心关键函数int reds_stream_send_msgfd(RedsStream *stream, int fd){ struct msghdr msgh = { 0, }; struct iovec iov; int r; const size_t fd_size = 1 * sizeof(int); struct cmsghdr *cmsg; // 使用联合体,保证cmsghdr和msg_control的对齐 union { struct cmsghdr hdr; char data[CMSG_SPACE(fd_size)]; } control; spice_return_val_if_fail(reds_stream_is_plain_unix(stream), -1); /* set the payload */ iov.iov_base = (char*)"@"; //发送的ascii码,一个字符 iov.iov_len = 1; //iov.iov_base的长度 msgh.msg_iovlen = 1; //只发送一个 struct iovec msgh.msg_iov = &iov; if (fd != -1) {//main中的第一个测试。ret = reds_stream_send_msgfd(st[0], 0); //上面的union体与msgh结构体建立联系,为辅助缓冲区和长度 msgh.msg_control = control.data; msgh.msg_controllen = sizeof(control.data); /* CMSG_SPACE() might be larger than CMSG_LEN() as it can include some * padding. We set the whole control data to 0 to avoid valgrind warnings */ memset(control.data, 0, sizeof(control.data));//清空数据 cmsg = CMSG_FIRSTHDR(&msgh);//从辅助缓冲区中取出一个辅助缓冲区,下面设置必要的字段值 cmsg->cmsg_len = CMSG_LEN(fd_size); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; memcpy(CMSG_DATA(cmsg), &fd, fd_size); //要传递的文件描述符 } //发送数据,不成功不罢休。 do { r = sendmsg(stream->socket, &msgh, MSG_NOSIGNAL); } while (r < 0 && (errno == EINTR || errno == EAGAIN)); return r;}
//关键函数,接收数据static ssize_tsock_fd_read(int sock, void *buf, ssize_t bufsize, int *fd){ ssize_t size; if (fd) { struct msghdr msg; struct iovec iov; union {//数据对齐 struct cmsghdr cmsghdr; char control[CMSG_SPACE(sizeof (int))]; } cmsgu; struct cmsghdr *cmsg; //设置接收缓冲区与长度 iov.iov_base = buf; iov.iov_len = bufsize; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; //设置辅助缓冲区与长度 msg.msg_control = cmsgu.control; msg.msg_controllen = sizeof(cmsgu.control); size = recvmsg(sock, &msg, 0); //接收数据 if (size < 0) { perror ("recvmsg"); exit(1); } cmsg = CMSG_FIRSTHDR(&msg);//取出第一个辅助缓冲区数据指针地址 if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(int))) { if (cmsg->cmsg_level != SOL_SOCKET) { fprintf(stderr, "invalid cmsg_level %d\n", cmsg->cmsg_level); exit(1); } if (cmsg->cmsg_type != SCM_RIGHTS) { fprintf(stderr, "invalid cmsg_type %d\n", cmsg->cmsg_type); exit(1); } //判读有效后,复制给fd ,文件描述符传输成功。 memcpy(fd, CMSG_DATA(cmsg), sizeof(*fd)); } else *fd = -1; } else { size = read(sock, buf, bufsize); if (size < 0) { perror("read"); exit(1); } } return size;}
[root@net01 tests]# ./test-stream event_loop_channel_event: channel event con, type, id, event: 0, 0, 0, 3event_loop_channel_event: channel event con, type, id, event: 0, 0, 0, 3[root@net01 tests]# pwd/root/spice-0.14.0/server/tests[root@net01 tests]#
阅读全文
0 0
- spice测试工程
- spice
- spice测试程序01-test-loop.c
- Spice project
- spice vdagent
- spice debug
- SPICE 小计
- SPICE简史
- 工程测试实验指导书
- JMeter 测试工程
- 创建 Robotium 测试工程
- 创建 instrumentation 测试工程
- c++工程包含测试
- XCODE 建立测试工程
- 创建 Robotium 测试工程
- Android工程测试
- 新建 Android 测试工程
- 新建 Android 测试工程
- Kruskal算法
- QT如何发布程序
- 详解MySQL基准测试和sysbench工具
- appium driver.swipe () 实现界面滑动执行报错 AttributeError: 'WebDriver' object has no attribute 'swipe'
- 骰子的游戏(牛客练习赛7)
- spice测试工程
- Apache与Tomcat有什么关系和区别
- linux-搭建nginx服务器--搭建php
- java编程思想 学习笔记 第一章
- 如何在Java中实现线程?
- unity shader学习笔记(十二)——Unity中的透明效果之双面渲染透明效果
- 11. 前缀码判定
- Tensor A must be from the same graph as Tensor B
- Java内存模型是什么?