Linux UDP通信 sendto发送数据时 指向接收数据主机地址信息的结构体 出错

UDP通信参考网址:

Linux编程之UDP SOCKET全攻略

参考这边文章自己在编写UDP通信客户端程序的时候,遇到了这个错误,

zhaochen@ubuntu14:~/code/UNIX/SVN_Ubuntu/udp$ g++ udpclient.cpp -o client 
udpclient.cpp: In function ‘int UdpSendData(char)’:
udpclient.cpp:99:94: error: cannot convert ‘sockaddr_in*’ to ‘const sockaddr*’ for argument ‘5’ to ‘ssize_t sendto(int, const void*, size_t, int, const sockaddr*, socklen_t)’
   rc = sendto(client_fd, deviceBuffer1, sizeof(deviceBuffer1), 0, &ser_addr, sizeof(ser_addr));  // UDP发送数据
                                                                                              ^
udpclient.cpp:110:73: error: no match for ‘operator*’ (operand type is ‘sockaddr_in’)
   rc = sendto(client_fd, sendBuffer, iSendDataByte, 0, ser_addr, sizeof(*ser_addr));  // UDP发送数据

参考上述网址中的代码查找后发现应该类似这样写:

第五第六个参数的定义以及写法应该是图中所示,但是我把 len 直接替换成 sizeof(*dst)就不可以,会报错。我自己的代码如下:

rc = sendto(client_fd, deviceBuffer1, sizeof(deviceBuffer1), 0, (struct sockaddr *)&ser_addr, sizeof(*ser_addr));		// UDP发送数据

后来改为

sizeof(struct sockaddr_in)

即可。附上我修改后的程序,相关参数设置如下:

struct sockaddr_in ser_addr;
int addr_len = sizeof(struct sockaddr_in);		// ser_addr 对方结构体接收数组
rc = sendto(client_fd, deviceBuffer1, sizeof(deviceBuffer1), 0, (struct sockaddr *)&ser_addr, addr_len);// UDP发送数据

解决这个问题的启发可以参考这个网址:http://velep.com/archives/934.html,截图如下:

参考其他经验发现,可能由于关键字拼写顺序不对导致报错,参考网址:https://blog.csdn.net/sweettool/article/details/76652243

总结一下此经验,作为备份!至于是否还有其他解决方法,暂时还不是很清楚,大家可以共同探讨!


2019.06.17更新

在编写发送数据函数的时候,发现我用的 recv 也可以接收到数据,但是在网上查资料基本上都说的是,用 recvfrom 来接收数据,后来用抓包工具抓了一下,发现真的是走的 UDP 通信协议,TCP上没有数据,然后就在想,为什么用 recv 也可以接收到数据,难道说不是必须用 recvfrom 这个函数来接收数据的吗?然后参考Unix高级教程第三版(P492-493页)我做了一下推测:

1、recv 可以指定标志来 接收数据,但是不能知道是谁发送过来的!

2、recvfrom 也可以接收数据,但是要求必须要知道是谁发送过来的,这个可以参考函数定义可得。

然后直接把 recv 替换成 recvfrom 后,类比 sendto 修改参数,发现还是会报出变量类型错误。

zhaochen@ubuntu14:~/code/UNIX/SVN_Ubuntu/udp$ g++ udpclient.cpp -o client 
udpclient.cpp: In function ‘int UDPClientRecvData()’:
udpclient.cpp:194:95: error: invalid conversion from ‘int*’ to ‘socklen_t* {aka unsigned int*}’ [-fpermissive]
  iRecvDataByte = recvfrom(client_fd, recvBuffer, MAXBUF, 0, (struct sockaddr *)&src, &addr_len);
                                                                                               ^
In file included from udpclient.cpp:5:0:
/usr/include/x86_64-linux-gnu/sys/socket.h:174:16: error:   initializing argument 6 of ‘ssize_t recvfrom(int, void*, size_t, int, sockaddr*, socklen_t*)’ [-fpermissive]
 extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n,

后来又参考之前看的经验,查找问题,发现,参考经验中 给出 len 变量的类型定义是:socklen_t ,但是我定义的是 int 类型的。

struct sockaddr_in ser_addr;
int addr_len = sizeof(struct sockaddr_in);		// ser_addr 对方结构体接收数组
rc = sendto(client_fd, deviceBuffer1, sizeof(deviceBuffer1), 0, (struct sockaddr *)&ser_addr, addr_len);// UDP发送数据

修改我自己代码对应的 addr_len 类型为 socklen_t 后,编译通过!下边给出正确的定义:

struct sockaddr_in ser_addr;
socklen_t addr_len = sizeof(struct sockaddr_in);		// ser_addr 对方结构体接收数组
iRecvDataByte = recvfrom(client_fd, recvBuffer, MAXBUF, 0, (struct sockaddr *)&ser_addr, &addr_len);

可能整个文章思路不是很清晰,以后会努力改进,大家慢慢看,有不懂得可以联系我,QQ:1446227671

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

FightingBoom

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

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

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

打赏作者

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

抵扣说明:

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

余额充值