通过Windows和Linux之间的插座与通信问题

问题描述 投票:0回答:2

我试图通过插座窗口(客户端)和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的期间,我没有问题,我可以正确地发送数据。

c linux windows sockets floating-point
2个回答
2
投票

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,等它不工作

停止挥舞着周围,希望一个作品尝试不同的变换。

在发送之前打印您的缓冲区的十六进制转储。签收后打印您的缓冲区的十六进制转储。填写你所期望的接收器和十六进制转储看到的结构,所以你可以看到其中的差别。


0
投票

请问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);
}
© www.soinside.com 2019 - 2024. All rights reserved.