未付初值,引发不确定后续错误一例!
参数要求传入内存空间大小
因未付初值,是个随机值,当小于所需大小时,返回错误结果。引起后续错误。
后续错误为。 客户端第一次连接不能成功,必须断开重新连接,才能连接成功。
一: 代码
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的整数或负数,则出问题。
这么复杂,挠头的问题,分析清楚后,解决却是这么简单。
难点在于, 也许你并不清楚传递参数的意义,你不知道是未付初值引起的。
根本原因也是因为,被调用函数采用了若内存空间不够,不干活,返回错误所引起。