背景
在我们的媒体库中使用基于asio封装一套IO模块,主要功能是媒体流的收发及转发。我们的系统使用的RTP协议作为流媒体协议,所以传输层协议是基于udp协议。
问题1
在sip信令协商成功后,开始流媒体收发时,偶现在异步收接口中一直报10061错误码,对应的错误码描述是连接被拒绝
出现这个错误,感觉很奇怪,媒体流的收发都是基于udp的,为什么会报连接被拒绝,又不是基于tcp的。检视代码未发现逻辑错误。但是通过抓包发现了问题:
在呼叫或点播一个编解码器时,sip信令协商成功后,会打开udp端口收发媒体流,两端打开端口的时机不一定是一致的,所以造成的一种现象是,一方给另一方发媒体流时,对方的端口并未打开,这时对方会直接回复端口不可达的ICMP包,在windows(linux不会有这个问题)上会将这个消息解释成连接被拒绝,所以上抛给应用层的错误码就是10061,很显然这并不是问题。
所以在asio中可以忽略掉10061错误码,继续调用异步收接口即可。
问题2
还有一种错误是报10022错误码,这个错误码的意思是提供了一个无效的参数,在使用udp时,报这种错误,大概率是在收发数据前没有调用 bind或connnect,应用层收发数据必须有个端口。所以如果不调用bind端口,那么一定要调用connect,相应的如果不调用connect则一定要调用bind。因为调用这两个接口的任意一个都是告知操作系统去对这个socket fd绑定一个端口,bind是明确的告知操作系统绑定什么端口,那么connect的调用则是操作系统会随机选取一个端口。
总结
-
10061错误码,可以直接忽略掉
-
10022错误码,这个时候需要检查代码是不是调用bind或connect失败,或者是根本没有调用这两个函数中的任一个