Find the answer to your Linux question:
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 11
Hi, We have a exercise to hand over in the few days to come. I tried to do it, I done most of the job but I am kind of ...
  1. #1
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8

    cleint/server programing problems

    Hi,

    We have a exercise to hand over in the few days to come. I tried to do it, I done most of the job but I am kind of stuck.

    ftclient <host> <port> <filename> <save as>
    ftserver <port> <size of each package> <delay between sent package>

    The client sends a filename to the server.
    If the server has the file, it sends 4 bytes to the client, which are size of the file (Using the stat() function on the server side). Else it sends one byte of 0xff, and the client closes the socket and unlink the file.
    If the file exist, the client gets ready to receive the packages.
    If in 10 seconds no pack arrives (I used select() ), the client aborts.
    If a package arrives, it has 1 byte of success, 4 bytes of offset, and the rest is the content of the message.

    What I am not able to understand is how the client receives the message in a buffer full of bytes and translate it. I know I must use the ntohl (network to host long) function.

    These are my question:

    What is the size I should use for the buffer ?
    How to copy the content of the message into another char * [] ?
    How to translate from the buffer full of bytes into something I can use ?
    How to use htonl ?

    Any code example would more then appreciated...

    This is what I wrote in the core so far:

    Loop in main

    Code:
    // Get ready to receive the content of the file
    while(received < fileSize ){
    	// Wait 10 seconds for the next package from the server
    	if( select(sd+1, &readfd, NULL, NULL, &timeout) != 0 ){
    		if( read(sd, &buffer, sizeof(buffer)) < 0 ){
    			perror("Error in reading the package\n")
    			exit(1);
    		}
    		// If first byte is -1 abort
    		if( atoi(ntohl(buffer[0]) != -1 ){
    			perror("Error sent from server\n");
    			exit(1);
    		}
    		offset = getOffset(buffer);
    		lseek(fd, offset, SEEK_SET);
    		copyMsg(buffer, &temp);
    		write(fd, temp, sizeof(temp), 0);
    	 }else{
    	        perror("Timeout\n");
    	        exit(1);
            }
    }
    getOffset function

    Code:
    int getOffset( char * buffer[] ){
    	static int place=1, i=1, size=0 ;
    	if( i == 4 ){
    		return(place);
    	}
    	if( (size = atoi(ntohl(buffer[i]))) > 0 ){
    		place *=  size ;
    	}
    	i++;
    	return(getOffset(buffer));
    }

  2. #2
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    I don't even know where to begin.
    I know I must use the ntohl (network to host long) function.
    Why?
    What is the size I should use for the buffer ?
    Any reasonable size will work.
    How to copy the content of the message
    Use, um, memmove()?
    into another char * [] ?
    Why are you using char *[]?
    How to translate from the buffer full of bytes into something I can use ?
    Why do you need to translate anything at all?
    How to use htonl ?
    Code:
    man htonl
    Code:
    atoi(ntohl( et cetera
    Now that's downright scary. You need to have a clear understanding of binary numbers, ASCII strings (particularly as representing numbers), and so on. I don't have time to explain it all, but you'll get a start if you scroogle this:
    Code:
    ASCII "binary number" representation
    This project is due in a few days? You have some serious gaps in understanding here. This is not to insult you or anything like that; it's a warning that you need to sprint to come up to speed in time for this assignment.

    To that end, I'd advise getting some face-to-face tutoring about data representation (and maybe about network programming). Not next week, but today, because once you have that understanding, you might have to do some serious redesign. I don't know; I didn't examine your code closely.

    Move, guy! This is scary. Good luck.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  3. #3
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8
    I know its scary, and I know I have a lot of gaps.
    No insult here, thats called honesty. And I appreciate it.

    So I will get on it and fill the gaps.

    Thanks a lot.

  4. #4
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8
    I did what you sugguested and come up with the following:

    Buffer and Temp are char [] ;

    Code:
    while(received < fileSize ){
    	// Wait 10 seconds for the next package from the server
    	if( select(sd+1, &readfd, NULL, NULL, &timeout) != 0 ){
    		if( read(sd, &buffer, sizeof(buffer)) < 0 ){
    			closeEverything("Error in reading the package\n", sd, fd);
    		}
    		// If first byte is -1 abort
    		if( ntohl(buffer[0]) != -1 ){
    			closeEverything("Error sent from server\n", sd, fd);
    		}
    		offset = getInteger(buffer, 1);
    		lseek(fd, offset, SEEK_SET);
    		memmove(temp, buffer+5, sizeof(temp));
    		if( write(fd, temp, sizeof(temp)) < 0 ){
    			closeEverything("could not write to file\n", sd, fd);
    		}
    	}
    	else {
    		closeEverything("Timeout\n", sd, fd);
    	}
    }
    Code:
    int getInteger( char buffer[], int start ){
    	uint32_t orig = 0;
    	uint32_t result = 0;
    	unsigned char byte0 = (unsigned char) buffer[start];
    	unsigned char byte1 = (unsigned char) buffer[start+1];
    	unsigned char byte2 = (unsigned char) buffer[start+2];
    	unsigned char byte3 = (unsigned char) buffer[start+3];
    	orig = (byte0 << 24) | (byte1 << 16) | (byte2 << 8) | byte3;
    	result = ntohl(orig);
    	return(result);
    }

  5. #5
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    I can't review your code right now line by line, but how's it going? Does the code work?
    --
    Bill

    Old age and treachery will overcome youth and skill.

  6. #6
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8
    After 3-4 days of reading and coding from morning till night, the client and server are able to transfer the data without any problems. It is working. I will post the code for the client and server when I am all done.

    Ignore the previous codes in this post, they are wrong.

    One problem remains:

    I have a buf that contains 500 bytes from the file. The sizeof(buf) is much bigger then 500 bytes.
    I have one byte of success.
    I have 4 bytes of offset.

    I want to put the success byte in buf[0]
    I want to put the offset bytes in buf[1] to bug[4]
    And I want to move all the bytes in buf, so that the first byte starts from buf[5] till buf[505].

    Any idea how to do that without using a loop ?
    Right now I am reading about memcpy and memmove.
    Is this the right direction ?

  7. #7
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8
    the communication between the client and server works fine.

    Code:
    //loop 
    	if( (i= read(fd, &buf, packSize, 0)) > 0 ){
    		printf("\nBytes from file read: %i\n", i);
    		memmove(buf+5, buf, sizeof(buf));
    		buf[0] = '0' ;	
    		memcpy(buf+1, &offset, sizeof(offset)); 
    		i = sendto(ssd, buf, packSize+5, 0, (struct sockaddr*)&client, clen);
    		printf("Bytes sent to client: %i\n", i);
    	}
    File exist getting file size: 688

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 60
    Bytes sent to client: -1

    Bytes from file read: 28
    Bytes sent to client: -1

    Why doesn't it send anything ?
    If I read from the file and send directly without manipulating the buffer, the client receives everything.
    The moment I use memcpy and memmove, the server sends nothing.

  8. #8
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    This is an answer to your post #6, not your post #7. You wrote post #7 while I was busy writing this.
    Right now I am reading about memcpy and memmove.
    Is this the right direction ?
    Yes, if you're willing to put up with a loop, because memcpy() and memmove() use a loop.

    I never use memcpy(). The reason is that if I ever want to slosh data between overlapping buffers, as you wish to do, there is a danger that it won't work. Indeed, the man page says this about memcpy():
    Code:
    The memcpy() function copies n bytes from memory area src to memory
    area dest.  The memory areas should not overlap.  Use memmove(3) if the
    memory areas do overlap.
    It isn't just superstition. When I run this shell script:
    Code:
    #!/bin/bash
    
    cat > tuesday.c <<EOD
    #include <stdio.h>
    #include <string.h>
    
    #define HOLLERITH 80
    
    int main(void)
    {
      char buffer[HOLLERITH];
    
      strcpy(buffer,"abcdefghijklmnopqrstuvwxyz");
      memcpy(buffer+1,buffer,strlen(buffer)+1);
      printf("memcpy() : %s\n",buffer);
    
      strcpy(buffer,"abcdefghijklmnopqrstuvwxyz");
      memmove(buffer+1,buffer,strlen(buffer)+1);
      printf("memmove(): %s\n",buffer);
    
      strcpy(buffer,"abcdefghijklmnopqrstuvwxyz");
      memcpy(buffer,buffer+1,strlen(buffer));
      printf("memcpy() : %s\n",buffer);
    
      strcpy(buffer,"abcdefghijklmnopqrstuvwxyz");
      memmove(buffer,buffer+1,strlen(buffer));
      printf("memmove(): %s\n",buffer);
    
      return 0;
    
    } /* main() */
    EOD
    cc -Wall tuesday.c -o tuesday
    ./tuesday
    EOD
    cc -Wall tuesday.c -o tuesday
    ./tuesday
    I get this output:
    Code:
    memcpy() : aaaaaefggijkkmnooqrssuvwwyz
    memmove(): aabcdefghijklmnopqrstuvwxyz
    memcpy() : bcdefghijklmnopqrstuvwxyz
    memmove(): bcdefghijklmnopqrstuvwxyz
    True, the third line of output is fine. But get into the habit of avoiding memcpy(), unless you have a good reason to use it.
    Any idea how to do that without using a loop ?
    Yes, and that will speed things up a bit. But first, this classic advice, in the form of two rules for the coder:
    1. Do not optimize.
    2. For experienced coders: do not optimize yet.

    Optimizing tends to make your code more complex, sometimes in subtle ways. Make sure (through timing experiments) that you spend a significant amount of time in the code that would be optimized; otherwise, it's not worth doing. It saves a few CPU cycles, but it drives up the cost of maintaining your code in the months ahead. Many coders fall into this trap.

    But if you want to get rid of that loop, don't read your data into buf in the first place. Read it into buf+5. Make sure you know how pointers work before you do this.
    --
    Bill

    Old age and treachery will overcome youth and skill.

  9. #9
    Linux Engineer wje_lf's Avatar
    Join Date
    Sep 2007
    Location
    Mariposa
    Posts
    1,192
    First: when you do the sendto(), always check the value you get back. If it's -1, then there was an error and you should look at errno. For more information:
    Code:
    man errno
    Second: in this statement
    Code:
    memmove(buf+5, buf, sizeof(buf));
    you picked the right function. Unfortunately, it works exactly as advertised.

    Let's say the buffer is 100 bytes long. In that statement, you attempt to move, well, um, 100 bytes.

    Byte 0 will be moved to byte 5.
    Byte 1 will be moved to byte 6.

    Care to guess where bytes 95, 96, 97, 98, and 99 will go?
    --
    Bill

    Old age and treachery will overcome youth and skill.

  10. #10
    Just Joined!
    Join Date
    Nov 2008
    Posts
    8
    Everything shifts +1 to the right, but since 99 is the last, it will be lost.
    I have a buf of 65000 bytes since UDP can not send more then that.
    There is no way the buf gets full.

Page 1 of 2 1 2 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
...