C 通过插座发送数据包
C++ sending a packet over socket
我正在尝试与安装的服务器程序进行通信。服务器以构造的数据包的形式发送并接收所有数据,该数据包遵循以下设置的设置int int int int string nullbyte这样:
Little Endian签名的INT-> ID的大小(4个字节) 类型的大小(4个字节) 车身大小(null终结器的最小值1) null字节至少为10,为值; <<<<<<<<
Little Endian签名int-> ID
Little Endian签名int->数据包类型
null终止ASCII字符串 -> Body
null字节
我已经设法读取了数据包,但是当我尝试使用密码发送数据包时,服务器完全忽略了它,这意味着数据包的方法是错误的。我像这样构造数据包:
void Packet::build(){
/*
* Create unsigned char vector to store
* the data while we build the byte array
* and create a pointer so the byte array can
* be modified by the required functions.
*/
std::vector<unsigned char> packet(m_size);
unsigned char *ptr = packet.data();
/*
* Convert each of the three integers as well
* as the string into bytes which will be stored
* back into the memory that ptr points to.
*
* Packet data follows format:
* int32 -> Size of ID + Server Data + body (minimum of 10).
* int32 -> ID of request. Used to match to response.
* int32 -> Server Data type. Identifies type of request.
* String -> Minimum of 1 byte for null terminator.
* String -> Null terminator.
*/
storeInt32Le(ptr, m_sizeInPacket);
storeInt32Le(ptr, m_requestID);
storeInt32Le(ptr, m_serverData);
storeStringNt(ptr, m_body);
/*
* Store the vector in member variable m_cmdBytes;
*
*/
m_cmdBytes = packet;
}
storeint32le:
void Packet::storeInt32Le(unsigned char* &buffer, int32_t value) {
/*
* Copy the integer to a byte array using
* bitwise AND with mask to ensure the right
* bits are copied to each segment then
* increment the pointer by 4 for the next
* iteration.
*/
buffer[0] = value & 0xFF;
buffer[1] = (value >> 8) & 0xFF;
buffer[2] = (value >> 16) & 0xFF;
buffer[3] = (value >> 24) & 0xFF;
buffer += 4;
}
Storestringnt:
void Packet::storeStringNt(unsigned char* &buffer, const string &s) {
/*
* Get the size of the string to be copied
* then do a memcpy of string char array to
* the buffer.
*/
size_t size = s.size() + 1;
memcpy(buffer, s.c_str(), size);
buffer += size;
}
最后,我将其发送给:
bool Connection::sendCmd(Packet packet) {
unsigned char *pBytes = packet.bytes().data();
size_t size = packet.size();
while (size > 0){
int val = send(m_socket, pBytes, size, 0);
if (val <= 0) {
return false;
}
pBytes += val;
size -= val;
}
return true;
}
packet :: bytes()只是返回m_cmdbytes
如注释中所述,您是:
-
制作假设关于编译器
int
数据类型的字节大小和末日。由于您的协议需要非常具体的字节大小和整数的endian,因此您需要强迫代码在准备数据包时遵循这些要求。 -
错误地使用
memcpy()
。您的源和目标缓冲区反向。 -
没有确保
send()
实际上正确发送完整数据包。
尝试更多类似的东西:
void store_uint32_le(unsigned char* &buffer, uint32_t value)
{
buffer[0] = value & 0xFF;
buffer[1] = (value >> 8) & 0xFF;
buffer[2] = (value >> 16) & 0xFF;
buffer[3] = (value >> 24) & 0xFF;
buffer += 4;
}
void store_string_nt(unsigned char* &buffer, const std::string &s)
{
size_t size = s.size() + 1;
memcpy(buffer, s.c_str(), size);
buffer += size;
}
...
std::vector<unsigned char> packet(13 + m_body.size());
unsigned char *ptr = packet.data(); // or = &packet[0] prior to C++11
store_uint32_le(ptr, packet.size() - 4);
store_uint32_le(ptr, m_requestID);
store_uint32_le(ptr, m_serverData);
store_string_nt(ptr, m_body);
...
unsigned char *pBytes = packet.data(); // or = &packet[0] prior to C++11
size_t size = packet.size();
while (size > 0)
{
int val = send(m_socket, pBytes, size, 0);
if (val < 0)
{
// if your socket is non-blocking, enable this...
/*
#ifdef _WINDOWS // check your compiler for specific defines...
if (WSAGetLastError() == WSAEWOULDBLOCK)
#else
if ((errno == EAGAIN) || (errno == EWOULDBLOCK) || (errno == EINTR))
#endif
continue;
*/
return false;
}
if (val == 0)
return false;
pBytes += val;
size -= val;
}
return true;
相关文章:
- boost::asio UDP 广播客户端仅接收"fast"数据包
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 发送固定大小的 UDP 数据包
- pcap_handler回调仅在使用 NPCAP v0.9991 时包含空数据包
- 在 c++ 中解析数据包数据的最佳方法是什么?
- 接受函数在发送数据包时等待
- 如何在 omnet++ 中发送自定义数据包?
- 数据包访问实践
- 在C++中创建一个简单的数据包路由器,如何跟踪"客户端"?
- 德拉吉诺 LG01-S 收到异常数据包并停止工作
- 将数据包从C++服务器发送到NodeJs服务器时出现MessagePack解码错误
- 使用C++将UDP数据包存储在Structure中
- FFmpeg av_read_frame从音频流返回数据包
- 为什么操作系统正在更改我的数据包的指定传出端口
- 是否可以将多个结构作为一个数据包存储在一个函数中,然后传递给其他函数并在那里提取?
- recvfrom 只收到几个数据包,之后它进入等待状态
- TOS字段从Linux的TCP插座上接收到的数据包获取
- C 插座未接收传入的数据包,在Python中工作
- C 通过插座发送数据包
- 插座上的数据包大小修改