philippe
philippe

Reputation: 3189

Trouble while reading from socket

I am trying to read characters from a socket; here is the function I created for this, largely inspired from Here, where I remove some unrelevant parts here (this sample is compiling correctly).

int process(int socketfd, void *buffer, int n)
{
  int totread = 0;
  char ch;
  int numread;

  for(;;)
  {
    numread = read(socketfd, &ch, 1);

    if(numread == 0) {
        if (totread == 0) {
            return 0;
        } else {
            break;
        }
    } else {
        if(totread < n-1) {
            totread++;
            printf("totread: %d\n", totread);
            printf("Here is OK, ch value gets printed %c\n", ch);
            *buffer++ = ch;
            printf("With help provided, this line gets printed\n");
            printf("But the value <%s> of buffer, is blank (<> output)\n, buffer);
        }
        if (ch == '\n') {
            printf("%c\n", ch);
            printf("%s\n", buffer);
            break;
        }
    }
}
return totread;
}

I can't understand why the second line does not get printed. Obviously, the *buf++ = ch instruction is faulty; But it looks like correct. It simply affects the character read to the next value of the array of characters buf. I don't see errors or warnings at compile time, the client disconnects after the first line gets printed, and the second one is not reached.

EDIT

Here is how I initialize my buffer:

char *buffer = "";
int l = process(newsockfd, buffer, 100);
printf("Number read (function network) %d\n", l);

This is probably not the appropriate way to do it; I have also tried specifying a fixed length such as char buffer = [255]; The function does not exit then but nothing get printed. I'm quite a newbie in C programming, many thanks for your help!

Upvotes: 0

Views: 100

Answers (2)

alk
alk

Reputation: 70979

int process(..., void * b, ...
{
  ...

  *b++ = ...

Dereferencing and/or incrementing a void-pointer is not valid C. The compiler should have at least warned you about this.

Recompile your code with all warnings on (for gcc pass the options -Wall -Wextra -pedantic for this). Then fix the code until no more warning are issued.


Referring your edit on how the function in question is called:

This

char *buffer = "";

does not declare a buffer, but just a pointer. This pointer points to a string literal of size 1. String literals a constant by definition.

To summarise: You provide to your process()-function a pointer to constant memory of size 1.

Issues with this:

  1. You cannnot read into constant memory.
  2. An even if 1. would not apply you could only read in 1 byte.

To fix this change the code as follows:

char buffer[100] = ""; /* Define a buffer of 100 characters size and 
                          initialise it to all `0`s. */
int l = process(newsockfd, buffer, 100);

As per process() blocking, you need to look at the read() function: If it gets called but the sender does not send anything it simply does not return as long as the connection is still up.

And: Make process() handle the value passed in as n.

Upvotes: 2

achoora
achoora

Reputation: 1350

Try changing the first line to char *buf = (char *) buffer; and compile using gcc with -Werror on

Upvotes: 0

Related Questions