Z
Z
Zohei2018-10-17 10:49:43
C++ / C#
Zohei, 2018-10-17 10:49:43

C. Where does the garbage at the end of the string (char) come from?

Good afternoon.
I master si by writing my ftp client-server.
The code for receiving the server response and its output:

char receiveData[DEFAULT_BUFLEN];
  memset(receiveData, 0, DEFAULT_BUFLEN);
  result = receive_data(receiveData);
  MessageBox(hWnd, (LPCSTR)receiveData, TEXT("123"), 0); // Без МУСОРА!!
  SendMessageA(hLogListBox, LB_ADDSTRING, 0, (LPARAM) receiveData); // с мусором!!
        SendMessage(hLogListBox, LB_ADDSTRING, 0, (LPARAM) receiveData); // с мусором!!

MessageBox shows the response normally
220 FTP Server(Version 6.00LS) ready.
But there is garbage in the listbox at the end of the line.
220 FTP Server(Version 6.00LS) ready.(МУСОР)
receive_data function
int receive_data(char *receiveData)
{
  char buffer[DEFAULT_BUFLEN];
  struct timeval timeout;
  int rc;
  fd_set fdr;
  
  FD_ZERO(&fdr);
  FD_SET(socket_desc, &fdr);
  timeout.tv_sec = 1; 
  timeout.tv_usec = 0;
  
  do {
        memset(buffer, 0, DEFAULT_BUFLEN);
        if (recv(socket_desc, buffer, DEFAULT_BUFLEN - 1, 0) < 0) {
            printf("recv failed: %d\r\n", WSAGetLastError());
      socket_desc_close();
      WSACleanup();
      return -1;
        }
        //printf("+ %s \r\n", buffer);
    rc = select(socket_desc + 1, &fdr, NULL, NULL, &timeout); 
    } while(rc);

  strcpy(receiveData, buffer);
  return 0;
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
R
res2001, 2018-10-17
@res2001

1. You are completely ignoring the size of the read data that recv returns.
recv does not commit to read the amount of data you pass to it as a buffer size. It returns the amount of data actually read.
2. When receiving information over the network, it is not guaranteed that the sent data will come all at once (and recv will be read in the same way), they can be fragmented, delayed, concatenated with the next packets, etc.
The analysis of the received data falls on the receiving side.
3. The data returned by recv usually does not have a null character at the end of lines. That is, if you are waiting for a string, then in order to further work with the received data as a string, you yourself must indicate the end of the string - force a null character. To do this, you must have room for a null character in the receive buffer for any size of received data.
Without this, most functions that work with strings will not give the correct result.
4. If you are waiting for a strictly defined data size, then you must provide in the code for reading the socket until you subtract the required amount of data. In this case, there may be several recv calls (see items 1, 2).
5. If you are waiting for some terminating character in the read data (the end of the line as in FTP), then you must independently check for the presence of this character (s) - recv will not do this for you. If there is no end of line in the current received data from recv, this does not mean that an error has occurred. This means that not all the data has been read and you still need to read it.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question