-2

Hi I designed a code to get the length of unknown data coming in to the socket I need help because I can't find where my code get stuck in this function. Thanks for any help

int recvlen(int s){ //peak all received data and returns the length                   
  char *request;
  int total;
  total= 1024;//initial size
  int numbytes;
  printf("\n entered recvlen\n");
  while(1){
    if(( request= (char *)realloc(request,sizeof(char)*total+1)) <=0){
      fprintf(stderr,"error in realloc no memory or fail");
      return -1;
    }
    if((numbytes= recv(s,request,sizeof(request),MSG_PEEK))==-1){//get request          
      fprintf(stderr,"\n error in receiveall \n");
      free(request);
      return -1;
    }
   if(numbytes != strlen(request)){
    total = numbytes+1;
    free(request);
    printf("\n recvlen returned total: %d\n",total);
    return total;//when the size is found                                             
   }
  total += total;
  }
    }
정영목
  • 1
  • 2
  • 2
    If you don't know how much data is being sent, how do you expect to know when to stop reading it? What protocol are you implementing that doesn't provide a way to know that? Even if your reading loop didn't have logic faults in it (which it does), it would just keep looping forever, unless `recv()` fails. Are you expecting to stop reading when it reports an `EWOULDBLOCK` error, for instance? You could use `ioctrl(FIONREAD)` on *Nix, or `ioctrlsocket(FIONREAD)` or `WSAIoctl(FIONREAD)` on Windows, to know how many bytes are currently pending on the socket without having to actually reading them. – Remy Lebeau Mar 29 '17 at 01:49
  • Why is code attempting an arithmetic compare on pointers with `char *request; ... if(( request= ...) <=0){`? – chux - Reinstate Monica Mar 29 '17 at 01:51
  • thank you for you kind comment, @RemyLebeau I was building a proxy server and was trying to get unknown length for request from the client. So I wanted to design recv() which can get unknown length of text. @ chux I attempted arithmetic compare to see if realloc returns 0 for failure in getting memory allocated. – 정영목 Mar 29 '17 at 02:22
  • 1
    @정영목 For a proxy implementation, just call `recv()` with a fixed buffer and let it tell you how many bytes were actually read, then send that many bytes to the other connection. And you can't compare a pointer to an integer. `realloc()` returns NULL on error. You shouldn't be saving the return value to the original variable directly, otherwise you will cause a memory leak on error. Save the new pointer to another variable first, and then assign that to the original variable if not NULL. On error, `realloc()` does not change the original memory, so you still have to `free()` it. – Remy Lebeau Mar 29 '17 at 02:37
  • 1
    @정영목 But, if you remove the unnecessary `recv()` loop, you can also remove `realloc()`, so the issue of leaking reallocated memory becomes moot. – Remy Lebeau Mar 29 '17 at 02:39

2 Answers2

1

I can't find where my code get stuck in this function

It doesn't 'get stuck'. It loops forever, because you aren't actually reading anything, because you used MSG_PEEK. Solution: don't.

NB if(numbytes != strlen(request)){ makes no sense whatsoever. There is no guarantee that request is ever null-terminated: in any case the test seems pointless.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • 2
    Also, reading `sizeof(request)` number of bytes is wrong, since `request` is a `char*` pointer. You would have to read `total` number of bytes instead, and then set `request[numbytes]=0` if you expect to use `strlen()` (which would be redundant since `strlen()` would then always be equal to `numbytes`, unless the data has embedded nulls in it) – Remy Lebeau Mar 29 '17 at 01:53
0

I think your software desing is wrong, why there is while(1), when you call recv(s,request,sizeof(request),MSG_PEEK)) you will get number of bytes in recv queue, then you have to read bytes from array. if you dont read, recv queue will overload and while(1) will never finish