Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ socket
I'm trying to send a files, with my server & client.
I just want to know how to send the file.
I tried few tutorials, but with one of them I got Debug error.
And the others, well its not easy to find very specific tutorial.
and i'm search the very easy one Big Grin | :-D
So if you can just show me with the function "send" and "recv" without the all connection, its will be great xD
Thanks Smile | :)
Posted 3-Aug-12 4:38am
Comments
Wes Aday at 3-Aug-12 9:44am
   
I got 456,000 results from a simple google search and you could not find anything?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Use an FTP library instead of coding this yourself.
Suppose you really want to do this yourself, then you need to start with the server. Run the server which will listen on a specific udp or tcp port.
Then you can create a client. In case of TCP it will first have to do a connect and then send data through the socket, in case of udp you can use sendto right away.
To do this correct is not so easy as it seams. That is why I suggest to use an FTP library unless you know what your are doing. Socket programming is advanced stuff. You either end up using a multithreaded application where the socket is being handled in a seperate thread, or using the select api on the socket and make the socket non blocking.
  Permalink  
v2
Comments
Albert Holguin at 3-Aug-12 9:52am
   
I would not recommend using UDP at all for file transfers.
Philip Stuyck at 3-Aug-12 9:59am
   
For UDP there is already a protocol that supports file transferts too: TFTP, for TCP it is of course FTP. TFTP is also used in the industry, it is a acked protocol. Usually FTP should be faster because it is based on TCP which used a sliding window mechanism. So the sender does not wait for an ack of each packet like TFTP does.
A client is usually not so hard to program but especially a TCP server can be really complicated dependending on what you want to do. The reason is that a TCP server is usually able to handle multiple connections at once.
Albert Holguin at 3-Aug-12 10:02am
   
If you use UDP for file transfers, you end up duplicating TCP functionality at the application layer. Not worth it at all.
Philip Stuyck at 3-Aug-12 10:10am
   
Well not if you use a TFTP library, these exist too. But my first choice would be to use a FTP library because of the reliability and speed.
Albert Holguin at 3-Aug-12 11:57am
   
Well a library is doing that behind the scenes, but it's having to replicate the reliability of TCP nonetheless.
pasztorpisti at 3-Aug-12 13:05pm
   
UPD is useful only when you want realtime and/or low latency stuff because of this: http://en.wikipedia.org/wiki/TCP_congestion_avoidance_algorithm
It might come handy for broadcasting as well but I dont know how well is supported by todays routers.
Albert Holguin at 3-Aug-12 14:50pm
   
Why are you telling me?
pasztorpisti at 3-Aug-12 15:28pm
   
Sorry, this post definitely went to the wrong place... oops
Philip Stuyck at 4-Aug-12 4:01am
   
TCP does not support broadcasting because it is a point to point connection oriented protocol. UDP does support broadcasting.
Philip Stuyck at 4-Aug-12 4:04am
   
Not true, TFTP uses a more simple reliability mechanism based on acking each packet. That is hardly the complexity of TCP.
Albert Holguin at 4-Aug-12 8:46am
   
Acknowledging each packet is how TCP achieves its reliability (plus either a parity check or crc, can't recall off the top of my head).
Philip Stuyck at 4-Aug-12 9:47am
   
TCP uses a sumcheck mechanism. Acking is not on packet basis but on sequence number basis. Also for the acking there is a delay with a 50ms timer, either the timer expires and TCP acks the last received in sequence packet, or the ack is sent earlier by piggybacking it on some message that has to be sent in reply.
Albert Holguin at 4-Aug-12 10:29am
   
So TCP does acknowledgement... That's exactly what I said.
Philip Stuyck at 4-Aug-12 10:51am
   
No it is not. Not each packet is acked.
Albert Holguin at 4-Aug-12 11:01am
   
Well, I'm not going to sit here and argue with you. I have better things to do.
Ido Hadar at 3-Aug-12 12:01pm
   
So you guys saying that if I using FTP its the best and fast way ?
And if not, its gonna be realy slowly .. ?
Philip Stuyck at 3-Aug-12 12:22pm
   
yes that is true. Unless it is your intent to learn about socket programming. Then this example is already too difficult to start with.
pasztorpisti at 3-Aug-12 13:11pm
   
Its usually possible to achieve better performance then most ftp libraries. We created a custom tool for our in house QA for downloading builds (that were more gigabytes large). This custom build downloader tool had 2 important features (and many small features like file filter for downloads): allowed at most X ppls to download in parallel (and had an algorithm that tried to give the same slice to as many ppl as it can), plus its download speed could saturate our local network (~100Megabytes/sec, and we have a quality router). To achieve this you have to play around with the send/recv buffer size of the socket, we set them to 1Megabytes if I remember right, and we played around with the packet size of send() (it was 4KB or 8KB finally, dont remember) - many say that this packet size can be important when you are about to saturate your network - I dont understand why because TCP is a stream, but maybe someone knows the internal impelmentation on windows or linux...
Albert Holguin at 3-Aug-12 15:16pm
   
TCP is only a stream at a high level...at a lower level its still individual packets.
pasztorpisti at 3-Aug-12 15:33pm
   
I don't know what the actual tcp implementation is, so I don't know what happens if I write many times 4K into the 1MB send buffer of the socket. Windows doesn't send it immediately but write size might have an effect on how that data is stored to that 1M send queue (and how it is sent later) depending on my send() size. Maybe you can add some more info on that! :-)
Philip Stuyck at 4-Aug-12 3:54am
   
Actually first there was TCP and IP came only later, as such a lot of functionality that is in IP you will also find in TCP. One of these things is to determine when to send a packet on the wire. Suppose a client send a lot of small packets of say 10 bytes, then TCP is going to wait a little while and put those 10 bytes on a queue because TCP knows that if he puts those 10 bytes on the wire he is not going to make optimal use of the mtu of the link layer. if the client keeps sending 10 byte packets, they will be appended to that queue and once your reach the mtu, it will be sent. If the user however expects some kind of ackknowledgement from his peer server, I am talking application logic here, then you will get lower transmission rates because each time a timer needs to expire. TCP is not going to wait forever until his internal queue reaches the mtu. You can switch of this behaviour and get faster transmission even for small packets. This is called the nagle algorithm.
You can get faster throughput than TCP using UDP if you keep pumping, but you will flood your network. TCP's is based on a windowing mechanism where the width of the window is calculated based on the roundtrip delay, that is the time it takes to send a packet and to receive an ack.
I know a lot of TCP because I am working in a telecom company and I am actually responsible for maintaining the sources of IP, TCP, UDP and ICMP. TCP is a very complex protocol compared to UDP.
pasztorpisti at 4-Aug-12 8:11am
   
I new nagle but thought it causes only latency (in case of small send sizes) that would not be a problem in case of transferring a big bunch of data. So 4K and 8K send sizes worked well because they reached the MTU! (Nagle wasnt turned off in my case). I just couldn't put together the pieces and find out the relationship between nagle and send size, thank you for the info!
Albert Holguin at 4-Aug-12 8:54am
   
A lot of the functionality that you find in IP is also in TCP? Wow... TCP is a layer beneath the IP layer. They don't do the same thing at all.
Philip Stuyck at 4-Aug-12 9:53am
   
IP is layer 3 and TCP is layer 4. So TCP runs on top of IP and not below. TCP has reassembly and fragmentation by taking the mtu into account, this is also done by IP. The fact that there was first TCP and only then IP is a historical fact.
Albert Holguin at 4-Aug-12 10:31am
   
On top, below... That's just semantics... Fact is, they don't do the same thing.
Philip Stuyck at 4-Aug-12 11:02am
   
Yeah right, ...
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

I'll show you the functional steps without code. You should be able to figure out the code.
 
0. Establish socket connection.
1. Read the input file in binary mode (for large files, only read in chunks).
2. Break up the file into chunks that fit into reasonable packet sizes.
3. Transmit packets.
4. On receive side, as you're receiving the binary data write it to a temporary file. Once all the chunks are received, close the file and name appropriately.
 
One thing you'll notice is... You'll need to know when a file transfer is about to begin, the name of the file, the file size (alternatively, transfer end). Hence, you'll need an application layer to your communications. FTP (as suggested in previous solution) is an application layer protocol that transfers files (hence the name, File Transfer Protocol). You could follow their guidelines, use a library, or just go ahead and code something yourself depending on your actual need or requirement.
  Permalink  
Comments
Philip Stuyck at 3-Aug-12 10:11am
   
in case of winsock you need to initialise the winsock library first.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Hi Ido!
I think your send and receive functions should look like this (only client send function and server receive function)...
// Client send function
nt Send(void* pvBuffer, int iStillToSend)
{
  int iRC = 0;
  int iSendStatus = 0;
  timeval SendTimeout;
  char *pBuffer = static_cast<char*>(pvBuffer);
 
  fd_set fds;
 
  FD_ZERO(&fds);
  FD_SET(Socket, &fds);
 
  // Set timeout
  SendTimeout.tv_sec  = 0;
  SendTimeout.tv_usec = 250000;              // 250 ms

  // As long as we need to send bytes...
  while(iStillToSend > 0)
  {
    iRC = select(0, NULL, &fds, NULL, &SendTimeout);
 
    // Timeout
    if(!iRC)
      return -1;
 
    // Error
    if(iRC < 0)
      return WSAGetLastError();
 
    // Send some bytes
    iSendStatus = send(Socket, pBuffer, iStillToSend, 0);   // Socket is of type 'SOCKET' and is the current connection socket

    // Error
    if(iSendStatus < 0)
      return WSAGetLastError();
    else
    {
      // Update buffer and counter
      iStillToSend -= iSendStatus;
      pBuffer += iSendStatus;
    }
  }
 
  return 0;
}
 

// Server receive function
int Receive(SOCKET Socket, void* pvBuffer, int iStillToReceive)
{
  int iRC = 0;
  int iReceiveStatus = 0;
  timeval ReceiveTimeout;
  char* pBuffer = static_cast<char*>(pvBuffer);
 
  // Set timeout
  ReceiveTimeout.tv_sec  = 0;
  ReceiveTimeout.tv_usec = 250000;             // 250 ms

  fd_set fds;
 
  FD_ZERO(&fds);
  FD_SET(Socket, &fds);
 
  // As long as we need to receive bytes...
  while(iStillToReceive > 0)
  {
    iRC = select(0, &fds, NULL, NULL, &ReceiveTimeout);
 
    // Timeout
    if(!iRC)
      return -1;
 
    // Error
    if(iRC < 0)
      return WSAGetLastError();
 
    // Receive some bytes
    iReceiveStatus = recv(Socket, pBuffer, iStillToReceive, 0);
 
    // Error
    if(iReceiveStatus < 0)
      return WSAGetLastError();
    else
    {
      // Update buffer and counter
      iStillToReceive -= iReceiveStatus;
      pBuffer += iReceiveStatus;
    }
  }
 
  return 0;
}
 
You can also see a great example here:
 
C++ Winsock Client To Server File Transfer - Made Easy[^]
 
and here:
http://www.daniweb.com/software-development/cpp/threads/295689/winsock-file-transfer-epic-slowness[^]
http://benshokati.blogspot.co.il/[^]
  Permalink  
Comments
pasztorpisti at 3-Aug-12 13:21pm
   
I would add a few code related notes:
Why do you quit the send/recv loop if select() times out? I would just check a flag in ever X intervals if the user requested a cancel on the send. A select timeout isnt an error. Maybe you have a slow network that wasnt able to send your bytes in time.
You are using async socket management (select), in this case you should switch your socket to nonblocking and then handle EWOULDBLOCK errors after send()/recv() and ignore them. Maybe this isnt that important in this case where you have to handle only with one socket without the chance to cancel a send, but if you want to introduce a cancel mechanism or you handle more sockets its very important to swithc to nonblocking sockets!!! select() might wake up because some bytes have arrived to a socket, then you start reading it with recv() but the network system just found out that the crc of the received data is invalid, and with a blocking socket you might just start blocking on your socket with recv() and your other socket or the cancel flag started starving! This checksum stuff is an existing scenario, never encountered it but I read about it on msdn in a Qxxxxxx article.
EDIT: Another thing: if recv returns 0 it usually means that the peer closed the other side of the connection.
Y.Desros at 4-Aug-12 2:04am
   
Dear pasztorpisti! Your explanations are not relevant.
If you think that the code is given by another member(by the way, he gave a few examples) is not good enough, then as a counter argument bring your code! and then you can explain why you think that your example is better than an example given by another member of the forum
pasztorpisti at 4-Aug-12 8:18am
   
Dear Y.Desros!
Can you make it a bit more clear what is irrelevant in my comment please?
The posted code is similar to the patterns I use when its about networking and after fixing the bugs I mentioned it will be a suitable answer. Anyway, my explanation contains some human readable information too that might be harder to extract from code. Even if the code remains as it is, its good enough with my comment to help the OP to put togehter a solution.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 5

If you want to use sockets, then you have to know some things
1. How to send and receive data via sockets. Just learn how to make simple TCP server and simple TCP client.
2. How to open and create, read and write files.
 
You may want to use some TCP based protocol, as FTP, HTTP, SMTP, SOAP, to send files. Same thing. But you have to follow the protocol. So, you will have to read protocol specification. It may look more complicated, but you will get much more interoperability with standard servers. For instance, send file to an FTP server, or receive file from a HTTP server.
 
Also you may want to just use standard protocols, and to not care about sockets. Use libraries, like WinINET, which is availabie in Windows. Or search one other via google.
  Permalink  
Comments
Ido Hadar at 3-Aug-12 12:10pm
   
I know to send and recv data with sockets ..
But look at my last comment. i post my functions ..
and its don't work perfect ..
So if i want just start with the oscket (without the protcols for now ..)
Just want to know what worng with the code, and why its not working ..
armagedescu at 3-Aug-12 12:20pm
   
Ok, I understand. First of all don't mix C stdio with C++ iostream. I see that you are closing file before reading from it. btw, you can use GetFileSize function from WinAPI. Other thing is that you send size. And you try to read 128 bytes from the client. For instance size is 3 digits, the rest 125 are the content of the file.
The last thing is that you use sendto/recvfrom. Why you don't use just send/recv?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

Guys I know I'm noob xD
But i'll show you what i did with few tutorials.
And its creating the file but its not write its right ..
 
I tried to send a .txt file with some text in it ..
and its create the file, without the text in it..
here the functions:
 
void FileRecive(char *Filename)
{
    FILE *File = fopen(Filename, "wb");
 
    // File size
    char Size[128];
    recvfrom(Socket, Size, 128, 0, (sockaddr*)&Addr, &Addrlen);
    Size[127] = '\0';
    int IntSize = atoi(Size);
 
    while(IntSize > 0)
    {
        char Buffer[1500];
 
        if(IntSize >= 1024)
        {
            recvfrom(Socket, Buffer, 1024, 0, (sockaddr*)&Addr, &Addrlen);
            fwrite(Buffer, 1024, 1, File);
        }
        else
        {
            recvfrom(Socket, Buffer, IntSize, 0, (sockaddr*)&Addr, &Addrlen);
            Buffer[IntSize] = '\0';
            fwrite(Buffer, 1024, 1, File);
        }
 
        IntSize -= 1024;
    }
 
    fclose(File);
}
 
void SendFile()
{
    std::ifstream File;
    File.open("C:\\Text.txt", std::ios::in| std::ios::binary| std::ios::ate);
    int Size = (int)File.tellg();
    File.close();
 
    char FileSize[10];
    itoa(Size, FileSize, 10);
 
    // Send size
    sendto(Socket, FileSize, strlen(FileSize), 0, (sockaddr*)&Addr, sizeof(Addr));
 
    FILE *MyFile = fopen("C:\\Text.txt", "rb");
 
    while(Size > 0)
    {
        char Buffer[1500];
 
        if(Size >= 1024)
        {
            fread(Buffer, 1024, 1, MyFile);
            sendto(Socket, Buffer, 1024, 0, (sockaddr*)&Addr, sizeof(Addr));
        }
        else
        {
            fread(Buffer, 1024, 1, MyFile);
            Buffer[Size] = '\0';
            sendto(Socket, Buffer, Size, 0, (sockaddr*)&Addr, sizeof(Addr));
        }
 
        Size -= 1024;
    }
 
    fclose(MyFile);
}
  Permalink  
Comments
pasztorpisti at 3-Aug-12 13:24pm
   
Sorry but I have to say that this is a totally bad solution. If you are using UDP then you have to put together a very complex piece of code that provides a reliable stream and it should contain something like this: http://en.wikipedia.org/wiki/TCP_congestion_avoidance_algorithm.
Instead of coding this whole UDP hell stuff you can use TCP that already contains these for you.
Albert Holguin at 3-Aug-12 15:20pm
   
He doesn't show how he established his socket, you're assuming its udp.
pasztorpisti at 3-Aug-12 15:26pm
   
You are right! :-)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 BillWoodruff 360
1 Mathew Soji 309
2 Maciej Los 270
3 DamithSL 225
4 Afzaal Ahmad Zeeshan 202
0 OriginalGriff 6,249
1 Sergey Alexandrovich Kryukov 5,853
2 DamithSL 5,183
3 Manas Bhardwaj 4,673
4 Maciej Los 3,865


Advertise | Privacy | Mobile
Web04 | 2.8.1411019.1 | Last Updated 3 Aug 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100