未付初值,引发不确定后续错误一例
2014-07-02 11:36
716 查看
未付初值,引发不确定后续错误一例!
参数要求传入内存空间大小
因未付初值,是个随机值,当小于所需大小时,返回错误结果。引起后续错误。
后续错误为。 客户端第一次连接不能成功,必须断开重新连接,才能连接成功。
一: 代码
struct sockaddr_in addr_client;
socklen_t addrlen; // 未付初始值,是个随机数。
// socklen_t addrlen=sizeof(struct sockaddr); //问题解决办法,加上初始化值
while (1)
{
printf("block by recvfrom ..........\n");
int n=recvfrom(sockfd,recv_buffer,256,0,(struct sockaddr *)&addr_client,&addrlen);
if(n==-1)
{
perror("recv error:");
continue;
}
printf("recvbuffer is %s\n",recv_buffer);
char IPDotDecimal[INET_ADDRSTRLEN]; //存放点分十进制IP地址
struct in_addr s = addr_client.sin_addr;
inet_ntop(AF_INET, (void *)&s, IPDotDecimal, sizeof(IPDotDecimal));
printf("addr_client: %s\n",IPDotDecimal);
printf("port_client: %d\n",addr_client.sin_port);
printf("addrlen: %d\n",addrlen);
printf("begin rtsp_analyse() ..........\n");
rtsp_analyse(sockfd,(struct sockaddr *)&addr_client,addrlen, recv_buffer);
}
二:症状。
第一次运行时,addr_client, port_client 都是0. 导致服务器不能向客户端发送数据。
addr_client: 0.0.0.0
port_client: 0
addrlen: 16
begin rtsp_analyse() ..........
sendto number = -1
sendto error: Invalid argument
但是客户端断开, 重新启动连接,则可以正常使用了。
addr_client: 192.168.3.126
port_client: 34019
addrlen: 16
begin rtsp_analyse() ..........
rtsp_analyse() success!
三: 原因及解决办法:
addrlen 初始值不合法,使得recvfrom 没有得到正确的返回值。addr_client 返回来0.0.0.0,
但是 addrlen 返回了正确值16。
由于addr_client 地址不合法,所以sendto 会返回 Invalid argument.
由于addrlen 在第一次相应之后得到了正确值,后续就正常了。
解决办法: 开始时要给addrlen 付给初值。
其它: 解决此问题,我曾经用wireshark 抓过包,确认错误出在server 端。
并且用gdb 跟踪过, addrlen 局部变量不付初值,是有随机性的。 有的版本编译出来
执行时是个大于16的正值,则没有问题, 而有的执行时是个0或小于16的整数或负数,则出问题。
这么复杂,挠头的问题,分析清楚后,解决却是这么简单。
难点在于, 也许你并不清楚传递参数的意义,你不知道是未付初值引起的。
根本原因也是因为,被调用函数采用了若内存空间不够,不干活,返回错误所引起。
参数要求传入内存空间大小
因未付初值,是个随机值,当小于所需大小时,返回错误结果。引起后续错误。
后续错误为。 客户端第一次连接不能成功,必须断开重新连接,才能连接成功。
一: 代码
struct sockaddr_in addr_client;
socklen_t addrlen; // 未付初始值,是个随机数。
// socklen_t addrlen=sizeof(struct sockaddr); //问题解决办法,加上初始化值
while (1)
{
printf("block by recvfrom ..........\n");
int n=recvfrom(sockfd,recv_buffer,256,0,(struct sockaddr *)&addr_client,&addrlen);
if(n==-1)
{
perror("recv error:");
continue;
}
printf("recvbuffer is %s\n",recv_buffer);
char IPDotDecimal[INET_ADDRSTRLEN]; //存放点分十进制IP地址
struct in_addr s = addr_client.sin_addr;
inet_ntop(AF_INET, (void *)&s, IPDotDecimal, sizeof(IPDotDecimal));
printf("addr_client: %s\n",IPDotDecimal);
printf("port_client: %d\n",addr_client.sin_port);
printf("addrlen: %d\n",addrlen);
printf("begin rtsp_analyse() ..........\n");
rtsp_analyse(sockfd,(struct sockaddr *)&addr_client,addrlen, recv_buffer);
}
二:症状。
第一次运行时,addr_client, port_client 都是0. 导致服务器不能向客户端发送数据。
addr_client: 0.0.0.0
port_client: 0
addrlen: 16
begin rtsp_analyse() ..........
sendto number = -1
sendto error: Invalid argument
但是客户端断开, 重新启动连接,则可以正常使用了。
addr_client: 192.168.3.126
port_client: 34019
addrlen: 16
begin rtsp_analyse() ..........
rtsp_analyse() success!
三: 原因及解决办法:
addrlen 初始值不合法,使得recvfrom 没有得到正确的返回值。addr_client 返回来0.0.0.0,
但是 addrlen 返回了正确值16。
由于addr_client 地址不合法,所以sendto 会返回 Invalid argument.
由于addrlen 在第一次相应之后得到了正确值,后续就正常了。
解决办法: 开始时要给addrlen 付给初值。
其它: 解决此问题,我曾经用wireshark 抓过包,确认错误出在server 端。
并且用gdb 跟踪过, addrlen 局部变量不付初值,是有随机性的。 有的版本编译出来
执行时是个大于16的正值,则没有问题, 而有的执行时是个0或小于16的整数或负数,则出问题。
这么复杂,挠头的问题,分析清楚后,解决却是这么简单。
难点在于, 也许你并不清楚传递参数的意义,你不知道是未付初值引起的。
根本原因也是因为,被调用函数采用了若内存空间不够,不干活,返回错误所引起。
相关文章推荐
- hive case when 引发错误一例 推荐
- hive case when 引发错误一例
- 错误笔记(1)——关于克隆虚拟机引发的后续问题
- hive case when 引发错误一例
- oracle删除表空间引发错误的解决方法 ORA-01122,ORA-01110,ORA-01203
- 【C/C++】Linux下system()函数引发的错误
- 主机名问题引发的错误 ORA-00…
- STM32F4 Discovery USB HID 工程 USB初始化引发硬件错误的原因
- Makefile调用Shell语句引发的一个错误
- VS2008环境下C++编程的LNK2019链接错误 后续不断补充
- 由Login.aspx引发编译器错误的解决方法
- 使用malloc、calloc函数分配内存空间和存储内容不匹配时引发的错误!
- ORA-00600 [3756]内部错误一例
- 安卓项目中使用JSON引发的一个小错误
- linux平台中java程序文件编码错误一例
- ORA-600 [4000] 错误解决一例
- 一次.Net项目路径变更引发的错误
- DLL中用malloc分配了一块内存,但是在exe程序中释放引发的错误:其原因可能是堆被损坏,这也说明 **.exe 中或它所加载的任何 DLL 中有 bug。
- 经验教训:Delphi中out string 被外部通过Dll调用引发的错误
- Oracle内部错误:ORA-00600[17175]一例