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 ...
- 11-28-2008 #1Just 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
getOffset functionCode:// 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); } }
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)); }
- 11-28-2008 #2
I don't even know where to begin.
Why?I know I must use the ntohl (network to host long) function.
Any reasonable size will work.What is the size I should use for the buffer ?
Use, um, memmove()?How to copy the content of the message
Why are you using char *[]?into another char * [] ?
Why do you need to translate anything at all?How to translate from the buffer full of bytes into something I can use ?
How to use htonl ?Code:man htonl
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:atoi(ntohl( et cetera
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.Code:ASCII "binary number" representation
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.
- 11-28-2008 #3Just 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.
- 11-29-2008 #4Just 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); }
- 12-01-2008 #5
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.
- 12-02-2008 #6Just 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 ?
- 12-02-2008 #7Just Joined!
- Join Date
- Nov 2008
- Posts
- 8
the communication between the client and server works fine.
File exist getting file size: 688Code://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); }
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.
- 12-02-2008 #8
This is an answer to your post #6, not your post #7. You wrote post #7 while I was busy writing this.
Yes, if you're willing to put up with a loop, because memcpy() and memmove() use a loop.Right now I am reading about memcpy and memmove.
Is this the right direction ?
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():
It isn't just superstition. When I run this shell script: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.
I get this output: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
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.Code:memcpy() : aaaaaefggijkkmnooqrssuvwwyz memmove(): aabcdefghijklmnopqrstuvwxyz memcpy() : bcdefghijklmnopqrstuvwxyz memmove(): bcdefghijklmnopqrstuvwxyz
Yes, and that will speed things up a bit. But first, this classic advice, in the form of two rules for the coder:Any idea how to do that without using a loop ?
- Do not optimize.
- 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.
- 12-02-2008 #9
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:
Second: in this statementCode:man errno
you picked the right function. Unfortunately, it works exactly as advertised.Code:memmove(buf+5, buf, sizeof(buf));
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.
- 12-02-2008 #10Just 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.


Reply With Quote