【问题标题】:do while loop for recv () in Winsock在 Winsock 中为 recv() 执行 while 循环
【发布时间】:2014-01-11 03:22:14
【问题描述】:

我正在通过 TCP 从 LabVIEW 向该 C 程序发送单个帧 (160x120) 来测试字节顺序。我设法将字节转换为 uint32 像素值,但问题是循环重复在控制台应用程序中打印接收到的数据。这里的重点是,我将打印接收到的 19200(160x120) uint32 值并在该值处停止打印,以便我可以检查帧的像素值。那可能吗 ?。编码: (我试图在 for 循环中将“len”更改为“160*120”,但我在控制台中得到了一些奇怪的值)。

int main(int argc , char *argv[])
{
WSADATA wsa;
SOCKET s , new_socket;
struct sockaddr_in server , client;
int c;
int iResult;
int receivedCount = 0;
char recvbuf[DEFAULT_BUFLEN];
int recvbuflen = DEFAULT_BUFLEN;
typedef unsigned int uint8_t;
unsigned int i;
size_t len;
uint8_t* p;
uint8_t value;

p = (uint8_t*)((void*)recvbuf);

do
{
  iResult = recv( new_socket, recvbuf, recvbuflen, 0);
  len = iResult/sizeof(uint8_t);

  for(i=0; i<len; i++)
    {
    value = p[i];
    printf("%lu\n",value);  
    }
}
while( iResult > 0 );

closesocket(new_socket);
WSACleanup();
}   

【问题讨论】:

  • 也许我的 C 已经生锈了,但为什么要双重转换 p = (uint8_t*)((void*)recvbuf);?在我看来,您可以在这里跳过额外的演员表......另外,您的数据是否可能由于大小而被分成多个数据包? 19200*sizeof(uint8_t) 似乎有很多数据可以放在一个数据包中
  • 数据作为字节流接收。跳过额外演员实际上是什么意思?
  • 我的意思是你可以直接写p = (uint8_t*)recvbuf;。我知道数据是作为字节流接收的,但我想知道该流是否真的是一组流而不仅仅是一个流;即,您可能会检查获得iResult&gt;0 的次数,因为我怀疑对于给定的数据集它会不止一次。
  • 我在那行放了一个断点,程序检测到断点。当我按下继续运行时,它随后会检测到它并在控制台中打印新的像素值。所以我认为你是对的。数据可能在多个数据包中被破坏。
  • 那么要回答您的问题,最好放置一个overallUintsRecieved 变量,该变量在value=p[i]; 之后递增,并在overallUintsRecieved &gt; 160*120 时为您提供指示符。现在您知道为什么使用for (i=0; i&lt; 160*120; i++)... 会给您带来坏数据:您正在读取超出当前读取数据包的末尾并进入未初始化的数据。

标签: c loops tcp winsock


【解决方案1】:

为了合并我的 cmets,我将如何重写您的代码:

int main(int argc, char *argv[]) {
  WSADATA wsa;
  SOCKET s, new_socket;
  struct sockaddr_in server, client;
  int c, iResult, receivedCount = 0;
  unsigned long totalReceived = 0, totalExpected=160*120;
  char recvbuf[DEFAULT_BUFLEN];
  int recvbuflen = DEFAULT_BUFLEN;
  typedef unsigned int uint8_t;
  uint8_t i, value;
  size_t len;
  uint8_t* p;

  p = (uint8_t*)recvbuf;

  do {
    iResult = recv(new_socket, recvbuf, recvbuflen, 0);
    len = iResult/sizeof(uint8_t);

    for (i=0; i<len; i++) {
      value = p[i];
      totalReceived++;
      printf("%lu\n", value);
      if (totalReceived >= totalExpected) {
        printf("Retrieved expected data\n");
      }
    }
  } while (iResult > 0);

  if (totalReceived < totalExpected) {
    printf("Received less than expected: %lu < %lu\n", totalReceived, totalExpected);
  }

  closesocket(new_socket);
  WSACleanup();
}

这包括“双重转换”更改,以及跨多个recv 调用捕获接收到的数据计数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-19
    • 2021-06-30
    相关资源
    最近更新 更多