gpt4 book ai didi

c++ - async_receive_from 没有收到所有东西

转载 作者:行者123 更新时间:2023-11-28 00:31:40 27 4
gpt4 key购买 nike

对于通过 UDP 进行的一些数据传输,我使用了来自 boost 的 async_receive_from 函数。我的接收函数是

        udp::socket socket_;
udp::endpoint remote_endpoint_;
boost::array<char, 200> recv_buffer_;

void start_receive()
{
std::fill(recv_buffer_.begin(), recv_buffer_.end(), '\0');
socket_.async_receive_from(boost::asio::buffer(recv_buffer_), remote_endpoint_, boost::bind(&udp_server_ping::handle_receive, this, boost::asio::placeholders::error));
}

void handle_receive(const boost::system::error_code& error)
{
if (!error || error == boost::asio::error::message_size)
{
for(int i = 0; i < 200; i++)
std::cout << recv_buffer_.c_array()[i];
std::cout << '\n';
for(auto it = boost::begin(recv_buffer_); it != boost::end(recv_buffer_); ++it)
std::cout << *it;
std::cout << '\n';
switch(recv_buffer_.c_array()[0])
{
case '#':
{
got_ping = true;
std::cout << "Gotcha!\n";
break;
}
case '$':
{
std::vector<char> char_buf(boost::begin(recv_buffer_), boost::end(recv_buffer_));
std::stringstream ss(std::string(char_buf.begin(), char_buf.end()));
std::vector<std::string> ip_list;
std::string ip;
std::cout << "Char_buf is: ";
for(auto it = boost::begin(recv_buffer_); it != boost::end(recv_buffer_); ++it)
std::cout << *it;
std::cout << "\nStringstream is: " << ss << '\n';
while(std::getline(ss, ip, '$'))
{
ip_list.push_back(ip);
};
ip_adr_ccd = ip_list[0];
ip_adr_daisy = ip_list[1];
std::cout << "ip_adr_ccd is: " << ip_list[1] << " and ip_adr_daisy is: " << ip_list[2] << '\n';
ip_adr_display.push_back(ip_list[3]);
break;
}
default:
break;

start_receive();
}

而我的传输功能是

DLL void transmit_ip(void)
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}


struct sockaddr_in sa;
struct hostent *hp;
SOCKET s;
std::string ip_adr;
if(Use == 'T')
ip_adr = ip_adr_ccd;
else
{
if(Use == 'S')
ip_adr = ip_adr_daisy;
else
ip_adr = ip_adr_display[0];
};
//Debug
//std::cout << "Pinging ip: " << ip_adr << '\n';
hp = gethostbyname(ip_adr.c_str());
if (hp == NULL) /* we don't know who this host is */
return;

memset(&sa,0,sizeof(sa));
memcpy((char *)&sa.sin_addr, hp->h_addr, hp->h_length); /* set address */
sa.sin_family = hp->h_addrtype;
sa.sin_port = htons((u_short)PORTNUM_UDP_OUT);

s = socket(hp->h_addrtype, SOCK_DGRAM, 0);
if (s == INVALID_SOCKET)
return;
std::string tx_str = '$' + ip_adr_ccd + '$' + ip_adr_daisy + '$' + retLocalIP() + '$';
//char str[] = "$127.0.0.1$128.0.0.1$129.0.0.1$";
std::cout << "tx_str is: " << tx_str << '\n';
char * buffer = new char[tx_str.length() + 1];
std::strcpy(buffer, tx_str.c_str());
int ret;
ret = sendto( s, buffer, sizeof(buffer), 0, (struct sockaddr *)&sa, sizeof(sa));
delete buffer;

}

当我使用 str[] 进行传输时,一切都很好,但是当我要传输我的 tx_str 时,接收器立即崩溃并且只显示 $192 作为接收数据。造成缓冲区溢出我做错了什么?

最佳答案

buffer 是一个 char* 时,sizeof(buffer) 返回指针的大小,而不是指向的长度字符串。似乎编译它的系统使用 4 个字节作为指针,因此只传输 4 个字符。收到 4 个字节后,handle_receive() 在尝试访问 ip_list 中的无效索引时调用未定义的行为,因为代码假定始终从接收消息中提取 3 个字符串.

要解决此问题,请显式向 sendto() 提供缓冲区大小,而不是使用 sizeof()。变化:

ret = sendto( s, buffer, sizeof(buffer), 0, ...)

到:

ret = sendto( s, buffer, tx_str.length() + 1, 0, ...)

可能还值得考虑检查输入并验证 ip_list 是在索引到它之前的预期大小。


char[]char* 是不同的类型。对于 char*sizeof() 将返回给定系统上指针的大小,而不是指针指向的字符串的长度。另一方面,对于 char[]sizeof() 将返回数组的大小。例如:

#include <iostream>

int main()
{
char str[] = "123456789ABCDEF";
char* buffer = new char[100];
std::cout << "char[] size = " << sizeof(str) << "\n"
"char* size = " << sizeof(buffer) << std::endl;
}

结果:

char[] size = 16
char* size = 8

关于c++ - async_receive_from 没有收到所有东西,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22690071/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com