Hi everybody!!
I'am new here, i write from Italy, so sorry for my bad english...:sick:
I 'am writing e client/server application using winsock, now i want to implement a file transfer from server to client. Now i thinck there are 2 way:
1)Open file, read data, send data(server); recive data,open file, save data to file (client)
2)Use TransferFile function that i find in API documents, but i don't know i to use it!! :rolleyes:
Please help me explaining how is better i do.
Thanks a lot.:wave:
NoHero
May 19th, 2004, 09:15 AM
The best way will be if you dont relay on this premade functions and gather your own filesending function.
Here are some possible solutions:
* Have two sockets: A control socket, where the client can request a file, and a transfer socket where you send the files
* Only one socket: Control & transfer with this socket.
You can make it like this:
Client: GET <filename>
Server: OK Data coming
Server: <filedata>
There is only one problem: How do the client now when the file ends?? You can use a specified block of data, but with the risk that this block may be in another file. So a real end is not given. So I think its better when you use 2 sockets.
*huuu* ... A great idea ... You could crypt the data ... I have to think about this idea ...
sry for this confusing, useless post
ng nohero
Xadoom
May 19th, 2004, 01:20 PM
Mmm...no 2 sockets, i have just the server with only one socket and i wants to implements this new capacity...my server sends a special sequence of characters when transfer complete, so this this isn't a problem. But how can i read the file? and how can client rebuild it?
Grazie.
:wave:
NoHero
May 21st, 2004, 02:23 PM
I did not understand your question ... but the nearest question is:
If you are using plain sockets, you send via "send"/"sendto" and retrieve data with "recv"/"recvfrom" ... Use the sendto,recvfrom functions for Datagramm sockets and the send/recv for streams.
is that what you meant??
Xadoom
May 21st, 2004, 02:55 PM
Yes, i solve so:
-read data from file
-send data with send()
-recive data with recv()
-create a file whit data.
Tnks:wave:
MikeAThon
May 21st, 2004, 05:20 PM
On the server side, you should:
-read file
-count number of bytes to be sent
-send the count
-send the file
On the client side you should:
-receive the count
-receive the file
On both sides, you must monitor the return values from the send() and recv() functions, to be certain that all data is sent/received. Sometimes all data is not sent (or received) and you need to loop on the send() (or recv()) function until all is completed. That's why you send the count of the file size, so that you know when it has been completely received.
See this thread for an example of someone who encountered problems until he did this: http://www.codeguru.com/forum/showthread.php?s=&threadid=294583#post947297
from above thread
You are writing code based on the mistaken belief that each send will result in exactly one recv. That's wrong. In fact, each send might result in zero recv's (where winsock is buffering up a larger send packet), one recv (lucky coincidence), or multiple recv's (where winsock needs to segment your buffer into multiple transmissions).
So, this code is wrong:
... <snip>
It's wrong because it assumes that you will recv ALL of the number of bytes specified by "len" in a single call to recv. In fact, you might recv far less. You need to keep track of the number of bytes actually received in each call, and keep calling recv until you have recv'd all that you expect.
Mike
NoHero
May 22nd, 2004, 07:24 AM
yes Mike is right ... and you should count in that the ping might be very high ... so the time between send and recv may be high (yes 6 seconds are high in this business) ... but I think you have enough stuff together to solve your problem right?
Xadoom
May 23rd, 2004, 06:54 AM
Thanks everybody.
I solve implementing from client side an asyncronous socket in this way:
//....
sock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0);
WSAAsyncSelect(sock,hwnd,WSA_EVENT,FD_CONNECT|FD_ACCEPT|FD_READ|FD_CLOSE|FD_WRITE|FD_CONNECT);
//....
//In the window procedure:
//....
case WSA_EVENT:
case FD_READ:
ioctlsocket(sock,FIONREAD,&sockByte);
recvbuf = new char[sockByte];
recv(sock, recvbuf, sockByte, 0 );
if(sockByte>0){
if(newFile==true){
char file[MAX_PATH]="C:\\prova.txt";
hFile = CreateFile(file,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_FLAG_OVERLAPPED,NULL);
newFile=false;
over.Offset=0;
over.OffsetHigh=0;
over.Internal=0;
over.InternalHigh=0;
over.hEvent=0;
}
WriteFileEx(hFile,recvbuf,sockByte,&over,NULL);
}
break;
In this way the recv() function is called many times still the file is complete recived, so is OK!!(it works!).
My question is now on server side,i use a sicronous socket whit this code:
The problem is that it works if the file si small (even 1Mb) but not if is a very big file....i think i have to send some byte for time, but how?
Grazie.
:wave:
NoHero
May 23rd, 2004, 07:00 AM
You send the whole file in one piece ... That will not work at bigger files ... Try sending in smaller pieces: This loop will run until no data could be read ...
And at the recv() section you should like this also. Just read with recv() a smaller piece as long, as long as you can. (like above)
Xadoom
May 23rd, 2004, 07:50 AM
Perfect!!!
Thank you very much, i had just wrote something like this, but your code is better.
Bye:wave:
NoHero
May 23rd, 2004, 07:53 AM
Originally posted by Xadoom
Perfect!!!
Thank you very much, i had just wrote something like this, but your code is better.
Bye:wave:
you are welcome :)
Xadoom
May 24th, 2004, 04:41 AM
Another question: how about the buffer size?
TCHAR lpTempBuffer[256];
I think is better a buffer more big as can, but how is the max dimension? Why you choose 256 Byte buffer?
Thanks.
:wave:
NoHero
May 24th, 2004, 05:35 AM
I don't know its a number that stuck in my brain like:
256, 1024, 2048 ...
I cant explain that ... thats just a habbit ...
Andreas Masur
May 24th, 2004, 07:21 AM
[Moved thread]
Xadoom
May 24th, 2004, 07:52 AM
Originally posted by NoHero
I don't know its a number that stuck in my brain like:
256, 1024, 2048 ...
I cant explain that ... thats just a habbit ...
Ok, but there is a size that is better?
More efficient? For example there is a MAX size that can i use?
Bye:wave:
NoHero
May 24th, 2004, 07:55 AM
No I dont think that there is a "all-around-size" for buffers ... If you make the buffer bigger you need more resources but the loop will go faster 'cause the buffer can handle more data at once. If you make the buffer smaller, you do not need so much resources but the loop will work longer ... you know what I mean? But do not care, its so a small factor, make it as big as you want
Xadoom
May 24th, 2004, 08:24 AM
Ok, thanks again.:wave:
NoHero
May 24th, 2004, 08:27 AM
Originally posted by Xadoom
Ok, thanks again.:wave:
You are welcome :D
joscollin
May 25th, 2004, 01:05 AM
Why MAX values if you are trying to split and send file data.
See NoHero's previous post...
RajiL
May 25th, 2004, 01:06 AM
Hi,
The size of the data packets sent to client from server shld be 4096 bytes.
Xadoom
May 25th, 2004, 07:25 AM
Originally posted by RajiL
Hi,
The size of the data packets sent to client from server shld be 4096 bytes.
Why??:wave:
RajiL
May 26th, 2004, 01:09 AM
It is optimal to have smooth data transfer rate
MikeAThon
May 26th, 2004, 01:33 AM
RajiL said
The size of the data packets sent to client from server shld be 4096 bytes.
I think RajiL is correct based on this thread: http://www.codeguru.com/forum/showthread.php?threadid=295544#post952302
The thread explains that 4k is the page size, and that when you do a recv/send the entire page is locked up, so even if you are using a buffer smaller than 4k you are still locking 4k memory thereby wasting bytes.
Of course, you can do multiples of 4k buffers. The only real limit would be the stack size, if the buffer is allocated off the stack.
Mike
Mathew Joy
May 26th, 2004, 01:36 AM
Originally posted by Xadoom
Hi everybody!!
I'am new here, i write from Italy, so sorry for my bad english...:sick:
I 'am writing e client/server application using winsock, now i want to implement a file transfer from server to client. Now i thinck there are 2 way:
1)Open file, read data, send data(server); recive data,open file, save data to file (client)
2)Use TransferFile function that i find in API documents, but i don't know i to use it!! :rolleyes:
Please help me explaining how is better i do.
Thanks a lot.:wave: As a side note let me add: TransferFile() API gives you the best performance of sending file over sockets. The file is read and send in the kernal mode. This API is ment for performance. If you can give the correct buffer size and have a good and fast recv at the client side then the result will be amazing
Xadoom
May 26th, 2004, 04:04 AM
Yes, but if i use TransmitFile() in server side, how i had to recive the file in client side?
:confused:
Mathew Joy
May 26th, 2004, 05:00 AM
you can use normal blocking recv(). You can use WriteFile() with overlapped parameter to do the writing (to a file) asynchronously (thereby faster performance).
Xadoom
May 26th, 2004, 05:35 AM
OK, so i have not to change the client....i will try.
Thanks:wave:
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.