do while цикъл за recv () в Winsock

Тествам реда на байтовете, като изпращам един кадър (160x120) от LabVIEW към тази C-програма през TCP. Успях да преобразувам байтовете в стойности на пиксели uint32, но проблемът е, че цикълът повтаря отпечатването на получените данни в конзолното приложение. Въпросът тук е, че ще отпечатам получените 19200(160x120) uint32 стойности и ще спра отпечатването при тази стойност, за да мога да проверя стойностите на пикселите на рамката. Това възможно ли е ?. Кодът: (Опитах се да променя "len" на "160*120" в for цикъла, но получих някои странни стойности в конзолата).

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();
}   

person Osman Esen    schedule 10.01.2014    source източник
comment
Може би моето C е ръждясало, но защо двойната отливка p = (uint8_t*)((void*)recvbuf);? Струва ми се, че можете да пропуснете допълнителното предаване тук... Също така, възможно ли е вашите данни да са разделени на множество пакети поради размера? 19200*sizeof(uint8_t) изглежда като много данни, които се очаква да се поберат в един пакет   -  person abiessu    schedule 10.01.2014
comment
Данните се получават като поток от байтове. Какво всъщност имаш предвид под пропускане на допълнителния състав?   -  person Osman Esen    schedule 10.01.2014
comment
Просто имам предвид, че можете да напишете p = (uint8_t*)recvbuf; директно. Знам, че данните се получават като поток от байтове, но се чудя дали може би потокът наистина е набор от потоци, а не само един; т.е. може да проверите колко пъти получавате iResult>0, защото подозирам, че ще бъде повече от едно за дадения набор от данни.   -  person abiessu    schedule 10.01.2014
comment
Поставих точка на прекъсване на този ред и програмата открива точката на прекъсване. Когато натисна продължи да се изпълнява, след това го открива след това и отпечатва нови стойности на пиксели в конзолата. Значи си прав според мен. Данните може да са повредени в множество пакети.   -  person Osman Esen    schedule 10.01.2014
comment
Тогава, за да отговоря на въпроса ви, би било добра идея да поставите променлива overallUintsRecieved, която се увеличава точно след value=p[i]; и ви дава индикатор, когато overallUintsRecieved > 160*120. И сега знаете защо използването на for (i=0; i< 160*120; i++)... ви дава лоши данни: вие четете отвъд края на текущо прочетения пакет данни и в неинициализирани данни.   -  person abiessu    schedule 10.01.2014
comment
Вие печатате байтове, а не uint32. Изпращате ли 32 битови стойности или 8 битови стойности?   -  person Chris J. Kiick    schedule 10.01.2014


Отговори (1)


За да обединя коментарите си, ето как бих пренаписал вашия код:

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 повиквания.

person abiessu    schedule 10.01.2014