我试图通过插座窗口(客户端)和Linux(服务器)之间的通信。我可以开始通信,但是当我发送数据时,会出现问题。主要的问题是,我尝试发送2个数据双人床和数据ulong的,但是当我的服务器(Linux)的上阅读我不能读取正确的值。如果我送,例如,double1 = 1.5,我收到0.0000服务器上。然后,如果我送double1 = 550.0我收到服务器-12382718421上...(垃圾)
我曾尝试使用htonl,再用ntohl,等它不工作我试图重新安排我从客户端发送帧的字节数,也就是发送B0 ... B7,而不是B7 ... B0 ...这是行不通的。我一直在寻找有关它的信息,但我无法找到任何东西,除了不同的操作系统之间的socket通讯是可能的,所以我知道有一个解决方案。
我的问题是:
1 - 是否htonl和nthol只有整数的工作?我可以使用浮点数据的转换?
2 - 什么是Linux和Windows帧的字节顺序?
3 - 我知道SENDTO()函数返回正在发送的字节数。我发送什么是20字节 - >(2 * 8个字节(双)+ 1 * 4字节(ULONG))= 20字节。但该函数返回24Bytes,这怎么可能呢?这是由于UDP协议头或者是包含Windows的其他信息?
感谢所有。
PD1:插座的设计是正确的。
PD2:Linux的Linux的期间,我没有问题,我可以正确地发送数据。
1 - 是否htonl再用ntohl和仅整数的工作?我可以使用浮点数据的转换?
这些功能仅针对整数定义。你需要知道每个平台在门店(包括字节序)增加一倍,以决定是否需要重新排序字节或执行一些其他的转换格式。
2 - 什么是Linux和Windows帧的字节顺序?
这个问题没有意义。你决定放什么在这个数据包,所以字节顺序是你发送任何刚。
传统上线的格式通常是大端,但很多现代的格式,理由是大多数同龄人将使用的x86小端。
针对您的特殊情况下,你在Linux上接受的事实是不是在Linux上运行的架构较少有关。您还没有提到,但假设x86_64的,存储方式和double
格式很可能是相同的发送代码。
NB。你或许应该使用固定大小的类型从<stdint.h>
,例如uint64_t
unsigned long
代替(假设是您的本意)。像long
类型具体可为甚至在同一平台上不同的ABI不同的尺寸。
3 - 我知道SENDTO()函数返回正在发送的字节数。我发送什么是20字节 - >(2 * 8个字节(双)+ 1 * 4字节(ULONG))= 20字节。但该函数返回24Bytes,这怎么可能呢?这是由于UDP协议头或者是包含Windows的其他信息?
显示你的代码。从sendto
的返回值不应大于你传递的长度参数越大,所以也许这值不是你的想法。
额外的长度绝对不是IP或UDP报头,这是超过4个字节反正。
我曾尝试使用htonl,再用ntohl,等它不工作
停止挥舞着周围,希望一个作品尝试不同的变换。
在发送之前打印您的缓冲区的十六进制转储。签收后打印您的缓冲区的十六进制转储。填写你所期望的接收器和十六进制转储看到的结构,所以你可以看到其中的差别。
请问htonl和nthol只有整数的工作?我可以使用这些转换浮法数据
要管理浮动例如你可以使用一个工会在uint32_t
反之亦然改造浮动,或使用float的指针强制转换为uint32_t
,反之亦然的指针,当然不投了浮子uint32_t
和反向
但你似乎工作的双,而不是浮动,你需要使用htobe64 / htole64 / be64toh / le64toh(endian.h
)这种情况下,如果他们没有被定义Windows下决定的顺序或您的数据包中的字节,并通过定义转换你自己
什么是Linux和Windows帧的字节顺序
该命令只取决于在CPU上,而不是在OS
我知道的sendto()函数返回正在发送的字节数。我发送什么是20字节 - >(2 * 8个字节(双)+ 1 * 4字节(ULONG))= 20字节。但该函数返回24Bytes,这怎么可能呢?这是由于UDP协议头或者是包含Windows的其他信息?
你只对有效载荷的访问,所有的页眉/页脚/等被隐藏于你
也许你发送一个结构,而不是让自己的数据包发送,在这种情况下,编译器只是不遵循相同的填充或长的尺寸是32B一个和64b上其他?
不要发送一个结构,拷贝数在管理端字节的向量,并以同样的方式提取出来
例如全部由手工做的,一个unsigned long读取8个字节/写入允许兼容即使他们有64B上其他主机和少:
#include <string.h>
void encDec32(char * a, char * b)
{
const int e = 1;
if (*((char *) &e)) {
memcpy(a, b, 4);
}
else {
a[0] = b[3];
a[1] = b[2];
a[2] = b[1];
a[3] = b[0];
}
}
void encDec64(char * a, char * b)
{
const int e = 1;
if (*((char *) &e)) {
memcpy(a, b, 8);
}
else {
a[0] = b[7];
a[1] = b[6];
a[2] = b[5];
a[3] = b[4];
a[4] = b[3];
a[5] = b[2];
a[6] = b[1];
a[7] = b[0];
}
}
void encodeU32(char ** buffer, uint32_t v)
{
encDec32(*buffer, (char *) &v);
*buffer += 4;
}
void encodeU64(char ** buffer, uint64_t v)
{
encDec64(*buffer, (char *) &v);
*buffer += 8;
}
void encodeFloat(char ** buffer, float v)
{
encDec32(*buffer, (char *) &v);
*buffer += 4;
}
void encodeDouble(char ** buffer, double v)
{
encDec64(*buffer, (char *) &v);
*buffer += 8;
}
void encodeUlong(char ** buffer, unsigned long v)
{
/* force on 8 bytes to be compatible with CPU 32 and 64 */
encodeU64(buffer, (uint64_t) v);
}
uint32_t decodeU32(char ** buffer)
{
uint32_t v;
encDec32((char *) &v, *buffer);
*buffer += 4;
return v;
}
uint64_t decodeU64(char ** buffer)
{
uint64_t v;
encDec64((char *) &v, *buffer);
*buffer += 8;
return v;
}
float decodeFloat(char ** buffer)
{
float v;
encDec32((char *) &v, *buffer);
*buffer += 4;
return v;
}
float decodeDouble(char ** buffer)
{
double v;
encDec64((char *) &v, *buffer);
*buffer += 8;
return v;
}
unsigned long decodeUlong(char ** buffer)
{
/* force on 8 bytes to be compatible with CPU 32 and 64 */
return (unsigned long) decodeU64(buffer);
}
/* for a struct */
typedef struct S {
unsigned long u; /* may be on 32 or 64 and not the same size on Linuw and Windows */
double d1;
double d2;
} S;
/* b is the block to send, it must be enough long */
/* return the number of bytes to send in a block through UDP */
size_t encodeS(char * b, S * s)
{
char * b0 = b;
encodeUlong(&b, s->u);
encodeDouble(&b, s->d1);
encodeDouble(&b, s->d2);
return b - b0;
}
/* b is the block read through UDP */
void decodeS(char * b, S * s)
{
s->u = decodeUlong(&b);
s->d1 = decodeDouble(&b);
s->d2 = decodeDouble(&b);
}