标题提到的报错,根本原因是公司定制的iperf命令代码比较老造成的,所以开源代码还是需要及时更新!
设备:android P
问题:PC上打开iperf服务端,安卓设备打开iperf客户端无法正常测试吞吐量,如下图:
安卓设备报错"unable to create a new stream: Invalid argument",PC端可以看到开始一瞬间有连接,后面因为客户端的原因关闭连接。
解决思路:
首先看报错,'无法创建新流'对应'case IECREATESTREAM',可以确定这个错误就出现在iperf_api的某个函数里,一搜发现都在iperf_new_stream()函数里,这里就简单了,排除掉前几个malloc,第一个函数mkstemp(),这个函数就有意思了,实际出问题的也是这里,先介绍一下这个函数。
mkstemp函数在系统中以唯一的文件名创建一个文件并打开,而且只有当前用户才能访问这个临时文件,并进行读、写操作。 mkstemp函数只有一个参数template,这个参数是个以“XXXXXX”结尾的非空字符串。mkstemp函数会用随机产生的字符串替换“XXXXXX”,保证文件名的唯一性。
通过man手册可以看到常见错误码有EEXIST和EINVAL:
1> EEXIST: 无法创建唯一的临时文件,参数template的内容未定义;
2> EINVAL: 针对mkstemp(),template的最后六个字符不是 XXXXXX;
值得一提的是,在glibc 2.0.6 以及更早的glibc库中这个文件的访问权限是0666,也就是说UNIX系统内所有的用户都能访问,这就会有大问题了,所以glibc 2.0.7以后的库这个文件的访问权限调整为0600。
mkstemp函数创建的临时文件不能自动删除,所以执行完 mkstemp函数后要调用unlink函数,unlink函数删除文件的目录入口,但临时文件还可以通过文件描述符进行访问,直到最后一个打开的进程关闭文件,或者程序退出后临时文件被自动彻底地删除。
出错原始代码段如下
struct iperf_stream *iperf_new_stream(struct iperf_test *test, int s)
{
int i;
struct iperf_stream *sp;
//问题就出在这里,template参数格式不正确
char template[] = "/data/data/iperf3.0.11";
......
/* Create and randomize the buffer */
sp->buffer_fd = mkstemp(template);
if (sp->buffer_fd == -1) {
i_errno = IECREATESTREAM;
free(sp->result);