CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 20
  1. #1
    Join Date
    Jul 2007
    Posts
    213

    sending and receiving file from socket

    now i really dont understand why !
    i made buffer of 10k for each send.
    each time fread read bytes, its send the byte 1 then send read bytes.
    else its send 0 for tell the client to stop looping - receive.

    all go great, sending sending then stuck without reason !

    here is my code:

    c++ server
    Code:
    case 0x01:
    			{
    				SocketR[1].p = false;
    				FILE * stream;
    				int h;
    				BYTE buffer[10000];
    				char rtyh[260];
    				CString t;
    				int y = SocketR[1].Receive(&rtyh, 260);
    				rtyh[y] = '\0';
    				int ss = GetSize(rtyh);
    				SocketR[1].Send(&ss, 4);
    				if (( stream = fopen(rtyh, "rb")) != NULL )
    				{
    					do
    					{
    						h = fread(&buffer, sizeof(BYTE), 10000, stream);
    						/*CString j;
    						j.Format("%d", h);
    						MessageBox(j);*/
    						if (h)
    							{
    								int c = 1;
    								if(SocketR[1].Send(&c, 4))
    									if(SocketR[1].Send(&h, 4))
    										if(SocketR[1].Send(buffer, h));
    											memset(&buffer, NULL, 10000);
    							}
    						else
    						{
    							int s = 0;
    							SocketR[1].Send(&s, 4);
    							break;
    						}
    					}
    					while (1);
    				}
    				SocketR[1].p = true;
    			}
    c# client
    Code:
    Int32 fsize;
    byte[] size = new byte[4];
    String source = src.Text;
    byte[] g = System.Text.Encoding.ASCII.GetBytes(source);
    SocketR.Send(BitConverter.GetBytes(0x01), 1, SocketFlags.None);
    SocketR.Send(g, source.Length, SocketFlags.None);
    SocketR.Receive(size, 4, SocketFlags.None);
    fsize = BitConverter.ToInt32(size, 0);
    FileStream fStream = new FileStream(dest.Text, FileMode.CreateNew, FileAccess.Write);
    			BinaryWriter bw = new BinaryWriter(fStream);
                byte[] data = new byte[10000];
                byte[] bamount = new byte[4];
                byte[] info = new byte[4];
                Int32 amount;
                Int32 iinfo;
                Int32 recv = 0;
    
                while(true)
                {
                    SocketR.Receive(info, 4, SocketFlags.None);
                    iinfo = BitConverter.ToInt32(info, 0);
                    if (iinfo == 1)
                    {
                        SocketR.Receive(bamount, 4, SocketFlags.None);
                        amount = BitConverter.ToInt32(bamount, 0);
                        SocketR.Receive(data, amount, SocketFlags.None);
                        bw.Write(data, 0, amount);
                        recv+= amount;
                        yu = recv.ToString() + "  /  " + fsize.ToString();
                        proglab.Invoke(new newUpdate_delegate(newUpdate)); 
                    }
                    else
                    {
                        bw.Close();
                        MessageBox.Show("Downloaded !");
                        break;
                    }
                }
    hope someone can help me.
    and please tell me too if my way of sending the file is ok or have a better one tnx

  2. #2
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: sending and receiving file from socket

    See the sample.
    Attached Files Attached Files
    Best regards,
    Igor

  3. #3
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    I put a Sleep(20); after the h = fread(&buffer, sizeof(BYTE), 10000, stream);

    and now its work fine !

    I am happy that its work fine but, i want to learn why its happend and how Sleep can help ?

    tnx

  4. #4
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: sending and receiving file from socket

    If you are using TCP, then you might need to re-adjust your thinking about TCP. TCP is a stream-based protocol, which means that the data on the wire is just a stream of bytes. Boundaries are not somehow inserted between individual calls to Send(). As a result, data on the wire from one Send() is often grouped together with data on the wire from a previous Send() and a subsequent Send().

    The code seems to be written as if you expect one call to Send() (at the sender side) to result in exactly one corresponding call to Receive() (at the recipient side). It won't. For example, your sender might call Send() three times, each with 10000 bytes. Your recipient might get a get a three groups of 10000 bytes too, but usually it will not. Usually it will get something else, such as one group of 30000 bytes, or two gorups of 15000 bytes, or one group of 10000 bytes followed by four groups of 5000 bytes each, or any combination at all.

    Your sender and your receiver must be written so that they both expect a pure stream of data, with no assumptions about how the stream might be grouped or re-grouped by all the routers on the path between the sender and the recipient.

    The reason why Sleep() makes a difference is that Sleep() causes your thread to yield to another active thread in the system, and as a consequence, it probably signals the TCP stack that it's OK to send all the data in its current buffer. In other words, through a luck coincidence of your current debug environment, the call to Sleep() forces a one-to-one correspondece between one call to Send() and one call to Receiv(). However, that lucky coincidence will not last forever, and it will almost certainly fail "in the field", and fail often. As an example, you are probably testing your program on a single machine using the loopback address (127.0.0.1). Try deploying your program in a release build and also across a LAN, using different machines. The program should almost certainly fail.

    Read this article. It talks about sending files using MFC CSocket, but the advice is still sound: "Network Transfer Of Files Using MFC's CSocket Class" at http://www.codeproject.com/KB/IP/Soc...eTransfer.aspx

    Mike

  5. #5
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    thank you,i tought on another thing !

    does it possible to call send and now continue to the next line untill send finish ?

    Send(xxx,xxx); \\ Stay here untill This send finish his work, then call the second send.
    Send(xxx,xxx);


    doest it possible ?

    then then the file transfer will work perfectly.

  6. #6
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: sending and receiving file from socket

    No, that's not possible. According to the layered model for networks, the application layer (that's your program) cannot dictate to the lower layers (like the TCP stack) how the lower layer should do its job. See "TCP/IP model" at http://en.wikipedia.org/wiki/TCP/IP_model

    When they first start programming for TCP, most people are surprised to learn about this "streaming" property of TCP, and their initial reaction is "how can I get around this"? You can't. Learn to appreciate the efficiencies that the TCP streaming model gives to all users of the overall bandwidth of the network, and then program according to the TCP streaming model.

    Mike

  7. #7
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: sending and receiving file from socket

    Quote Originally Posted by yoni1993
    Send(xxx,xxx); \\ Stay here untill This send finish his work, then call the second send.
    Send(xxx,xxx);


    doest it possible ?
    Yes, it's possible once you interleave your sending with receiving of some server's reply (like "OK" or something). Then you have to take care of letting the server side to know about to start your custom session, acknowledging every chunk received and closing your session - this is what they call a "custom protocol". Do you really need this?
    Best regards,
    Igor

  8. #8
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: sending and receiving file from socket

    Just to be clear on this point, what I think Igor is suggesting is something like this:
    Code:
    // awful pseudo-code
    Send( 10000 bytes );
    while ( Receive( 2 bytes ) != "OK") wait;
    Send ( next 10000 bytes )
    while ( Receive ( 2 bytes ) != "OK" ) wait;
    // etc ..
    In other words, wait for an acknowledgement of each 10000 bytes before sending the next 10000 bytes.

    But without waiting for an acknowledging handshake, there is no way to make the Send() function wait intrinsically for the recipient to receive all data, before exiting the Send() function.

    Mike

    PS: Thanks to Igor for pointing out that it's not impossible to get the OP's desired result. The performance would be terrible (as I think Igor is suggesting), and the OP will probably not want implement this for performance reasons, but it is not, in fact, impossible.
    Last edited by MikeAThon; December 12th, 2007 at 11:38 AM.

  9. #9
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: sending and receiving file from socket

    Mike, that exactly was my point. Actually, I cannot see any reason for "waiting" for the end-of-send "event", as well as I cannot see how somebody could benefit from the knowing that chunk was actually sent.

    The nature of TCP connection is to provide any possible efforts to transfer the data exactly as it was sent. It seems like the guy just tries to duplicate some TCP features.
    Best regards,
    Igor

  10. #10
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    No, im not searching to duplicate TCP features (i dont know how you tought this )
    now i understood well that TCP socket not always sending/receiving the requested bytes.

    Thank you very much for this lesson

  11. #11
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    Another questions, this is happen only to MFC Sockets or to all other socket ? (C#, Pure C++ [Not MFC]).

    Cause i made my program in MFC C++ and still have the same problem,
    i made the while loop untill it receive all the byte exactly same way as the project you gave (from code project), works well in my local computer but when i connect to a LAN computer, its not work, i put a break point and its lead me the receive while loop, i dont know why its happen.

    Now i go to try it in C++ (Console Application [The Server]).
    Last edited by yoni1993; December 14th, 2007 at 05:07 AM.

  12. #12
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    How come ?

    its work great in console application !

    without the while loop for send all non-sent bytes

    I tested it on two computer via internet and work great !

    why its happen ?

  13. #13
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: sending and receiving file from socket

    TCP works the way it works regardless of the OS and the sockets you use. It's always a streaming protocol, and it always is free to group and regroup your sent bytes into whatever chunks it wants to. For example, there's one algorithm (Nagle) that is precisely designed to group all sends of small amounts of bytes into one packet, until a prior packet is ACK'd. Another example is the re-transmisson algorithm: in the case of a re-transmission due to a lost packet, the recipient will receive everything from the lost packet onwards in one big chunk.

    These algorithms are part of TCP itself, and are independent of the OS or the socket implementation. Thus, they will characterize TCP regardless of whose system it's run on.

    So, the fact that "its work great in console application without the while loop for send all non-sent bytes" is probably a coincidence for now, and will exhibit the behavior you described earlier at some time in the future.

    If you have specific questions, you should show us your code, since it probably has changed alot since when you first posted it.

    Mike

  14. #14
    Join Date
    Jul 2007
    Posts
    213

    Re: sending and receiving file from socket

    Mike, i was reading some info about "TCP VS UDP", and i found that UDP is not "guaranteed delivery" and TCP does !

    But CSocket class from MFC does mistake as the article said (which you gave me to read).

    thats why TCP socket on win32 console application works fine !

    here is the article which ive found about TCP VS UDP.

    http://www.skullbox.net/tcpudp.php

    beside, thank you for all this help

  15. #15
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: sending and receiving file from socket

    Quote Originally Posted by yoni1993
    Mike, i was reading some info about "TCP VS UDP", and i found that UDP is not "guaranteed delivery" and TCP does !

    But CSocket class from MFC does mistake as the article said (which you gave me to read).

    thats why TCP socket on win32 console application works fine !

    here is the article which ive found about TCP VS UDP.

    http://www.skullbox.net/tcpudp.php

    beside, thank you for all this help
    TCP actually makes two guarantees that UDP does not. The first is guaranteed delivery, as you say. Te second is in-order delivery: TCP guarantees that the order in which the sender streams out the bytes is the order in which the recipient will receive them. UDP does not make this guarantee, and it's possible (maybe due to different routings) that a second datagram reaches a recipient before a first datagram that was sent first.

    But guarantees of TCP don't change simply because one program uses a console approach and the other a GUI approach. There is still something wrong with your approach. CSocket is fine. The article doesn't say there is something wrong with CSocket; it merely says that the programmer needs to understand TCP or he will make a mistake in programming.

    Mike

Page 1 of 2 12 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
  •  





Click Here to Expand Forum to Full Width

Featured