使用 Seagull 协议流量生成器的自定义 UDP 协议的 sendto() 失败
sendto() fails for Custom UDP Protocol, using Seagull Protocol Traffic Generator
我是网络、协议和套接字方面的新手运行,但这个问题已经困扰我好几天了,我似乎找不到解决方案。我正在使用 Seagull, an open source multi-protocol traffic generator (source code),创建一个带有自定义 UDP 的客户端。不幸的是,没有人真正跟上这个软件了,其他人也遇到过这个问题,但没有解决方案,它可能是生成器软件中的一个错误。我能够编写 运行 流量生成器所需的 XML 脚本,当我 运行 本地环回 (127.0.0.1) 上的客户端时,生成器工作正常,我能够收集数据包并使用 Wireshark 对其进行分析,它们包含正确的数据。
我现在正尝试使用此客户端向本地网络 (192.x.x.x) 上的服务器发送消息,但 Seagull 始终无法发送消息。这不是网络问题,因为我已经能够 ping 地址而没有丢包。我已经将错误的来源追溯到 sendto()
函数,该函数由于参数无效而一直失败。当目标设置为本地环回和其他 IP 并且传递给 sendto() 函数的参数完全相同时,我使用 GDB 逐步执行了代码,除了 [=12= 中的不同 IP 地址之外] 结构,这当然是预期的。但是,当我在 sendto()
中的系统调用之后查看寄存器时,包含消息长度值的寄存器在调用中途变为负数,这就是从函数返回的值call-本地环回网络不会发生这种情况。这是调用 sendto()
并失败的代码部分:
size_t C_SocketWithData::send_buffer(unsigned char *P_data,
size_t P_size){
// T_SockAddrStorage *P_remote_sockaddr,
// tool_socklen_t *P_len_remote_sockaddr) {
size_t L_size = 0 ;
int L_rc ;
if (m_write_buf_size != 0) {
// Try to send pending data
if (m_type == E_SOCKET_TCP_MODE) {
L_rc = _call_write(m_write_buf, m_write_buf_size) ;
} else {
L_rc = _write(m_write_buf, m_write_buf_size) ;
}
if (L_rc < 0) {
SOCKET_ERROR(0,
"send failed [" << L_rc << "] [" << strerror(errno) << "]");
switch (errno) {
case EAGAIN:
SOCKET_ERROR(0, "Flow control not implemented");
break ;
case ECONNRESET:
break ;
default:
SOCKET_ERROR(0, "process error [" << errno << "] not implemented");
break ;
}
return(0);
其中 _write()
是 sendto()
的包装器。
我不太确定是什么原因导致它这样做,我花了几个小时查看源代码并跟踪发生了什么,但一切似乎都很正常,直到缓冲区长度被修改系统调用。我查看了 socket()
初始化、绑定和其他函数,但一切似乎都很好。如果有人对 Seagull 有任何经验或此问题,请告诉我您是否有任何建议。我浏览了本网站上几乎所有 sendto()
相关问题,但没有找到解决方案。
我正在 运行通过 Windows 10 主机上的虚拟机 (Virtualbox) 在 Ubuntu v 14.04 上连接客户端,我正在尝试向其中发送消息。提前致谢!
经过几天的调试和查看源代码,我找到了这个问题的答案,我想更新这个,以防将来有任何可怜的人遇到同样的问题。最初的 Seagull 实现总是在调用 send
/sendto
之前尝试绑定套接字。在这种情况下,由于 sendto
自动绑定套接字,因此我能够删除这种情况下的绑定。
C_SocketClient::_open 中的原始实现(C_Socket.cpp 第 666 行):
} else {
L_rc = call_bind(m_socket_id,
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
编辑版本:
} else {
L_rc = call_bind(m_socket_id,
/* UDP Does not need to bind first */
if(m_type != E_SOCKET_UDP_MODE) {
L_rc = call_bind(m_socket_id,
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
} else {
L_rc = 0;
}
现在 Seagull 可以工作了,我可以发送我的自定义协议了!我打开了原始源代码的拉取请求,以便可以修复此问题。
我是网络、协议和套接字方面的新手运行,但这个问题已经困扰我好几天了,我似乎找不到解决方案。我正在使用 Seagull, an open source multi-protocol traffic generator (source code),创建一个带有自定义 UDP 的客户端。不幸的是,没有人真正跟上这个软件了,其他人也遇到过这个问题,但没有解决方案,它可能是生成器软件中的一个错误。我能够编写 运行 流量生成器所需的 XML 脚本,当我 运行 本地环回 (127.0.0.1) 上的客户端时,生成器工作正常,我能够收集数据包并使用 Wireshark 对其进行分析,它们包含正确的数据。
我现在正尝试使用此客户端向本地网络 (192.x.x.x) 上的服务器发送消息,但 Seagull 始终无法发送消息。这不是网络问题,因为我已经能够 ping 地址而没有丢包。我已经将错误的来源追溯到 sendto()
函数,该函数由于参数无效而一直失败。当目标设置为本地环回和其他 IP 并且传递给 sendto() 函数的参数完全相同时,我使用 GDB 逐步执行了代码,除了 [=12= 中的不同 IP 地址之外] 结构,这当然是预期的。但是,当我在 sendto()
中的系统调用之后查看寄存器时,包含消息长度值的寄存器在调用中途变为负数,这就是从函数返回的值call-本地环回网络不会发生这种情况。这是调用 sendto()
并失败的代码部分:
size_t C_SocketWithData::send_buffer(unsigned char *P_data,
size_t P_size){
// T_SockAddrStorage *P_remote_sockaddr,
// tool_socklen_t *P_len_remote_sockaddr) {
size_t L_size = 0 ;
int L_rc ;
if (m_write_buf_size != 0) {
// Try to send pending data
if (m_type == E_SOCKET_TCP_MODE) {
L_rc = _call_write(m_write_buf, m_write_buf_size) ;
} else {
L_rc = _write(m_write_buf, m_write_buf_size) ;
}
if (L_rc < 0) {
SOCKET_ERROR(0,
"send failed [" << L_rc << "] [" << strerror(errno) << "]");
switch (errno) {
case EAGAIN:
SOCKET_ERROR(0, "Flow control not implemented");
break ;
case ECONNRESET:
break ;
default:
SOCKET_ERROR(0, "process error [" << errno << "] not implemented");
break ;
}
return(0);
其中 _write()
是 sendto()
的包装器。
我不太确定是什么原因导致它这样做,我花了几个小时查看源代码并跟踪发生了什么,但一切似乎都很正常,直到缓冲区长度被修改系统调用。我查看了 socket()
初始化、绑定和其他函数,但一切似乎都很好。如果有人对 Seagull 有任何经验或此问题,请告诉我您是否有任何建议。我浏览了本网站上几乎所有 sendto()
相关问题,但没有找到解决方案。
我正在 运行通过 Windows 10 主机上的虚拟机 (Virtualbox) 在 Ubuntu v 14.04 上连接客户端,我正在尝试向其中发送消息。提前致谢!
经过几天的调试和查看源代码,我找到了这个问题的答案,我想更新这个,以防将来有任何可怜的人遇到同样的问题。最初的 Seagull 实现总是在调用 send
/sendto
之前尝试绑定套接字。在这种情况下,由于 sendto
自动绑定套接字,因此我能够删除这种情况下的绑定。
C_SocketClient::_open 中的原始实现(C_Socket.cpp 第 666 行):
} else {
L_rc = call_bind(m_socket_id,
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
编辑版本:
} else {
L_rc = call_bind(m_socket_id,
/* UDP Does not need to bind first */
if(m_type != E_SOCKET_UDP_MODE) {
L_rc = call_bind(m_socket_id,
(sockaddr *)(void *)&(m_remote_addr_info->m_addr_src),
SOCKADDR_IN_SIZE(&(m_remote_addr_info->m_addr_src)));
} else {
L_rc = 0;
}
现在 Seagull 可以工作了,我可以发送我的自定义协议了!我打开了原始源代码的拉取请求,以便可以修复此问题。