记一次UDP的sendto函数错误解决

错误现象

在编写使用select函数的TCP和UDP回射程序,出现UDP的sendto错误,现象如下:

  • 服务端正常启动后,调用select函数监听TCP和UDP套接字, 可以正常处理TCP请求。

  • UDP客户端可以连接到服务端,但接收标准输入后无回显,阻塞于recvfrom。

解决过程

经排查,发现服务端处理UDP请求的代码有问题,如下:

typedef struct sockaddr SA;
void udp_echo(int udpfd) {
	int n;
	char recvline[MAXLINE];
	struct sockaddr_in cliaddr;
	socklen_t len;
	n = recvfrom(udpfd, recvline, MAXLINE, 0, (SA*)&cliaddr, &len);
	sendto(udpfd, recvline, n, 0, (SA*)&cliaddr, len);
}

udp_echo函数,先用recvfrom读取UDP客户端发送的字符串,再使用sendto将该字符串送回客户端。代码中没有判断recvfrom, sendto函数的返回值,为了获取出错信息改写如下:

void udp_echo(int udpfd) {
	int n;
	char recvline[MAXLINE];
	struct sockaddr_in cliaddr;
	socklen_t len;
	if((n = recvfrom(udpfd, recvline, MAXLINE, 0, (SA*)&cliaddr, &len)) < 0) {
		err_sys("recvfrom error");
	}
	if(sendto(udpfd, recvline, n, 0, (SA*)&cliaddr, len) != n) {
		printf("error: %s\n", strerror(errno));
		err_sys("sendto error");
    }
}

再运行程序,输出如下:

$ error: Invalid argument

$ sendto error

错误原因在于cliaddr参数没有初始化。sockaddr_in结构体在使用之前,需要先使用bzero/memset函数初始化为0,否则出现赋值不完整导致参数无效。

总结:
  • 变量使用之前最好初始化。

  • 注意判断函数的返回值,可以使用包裹函数。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

pcj_888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值