Sign in to follow this  
AntonyCoder

Sending Files(Maps etc) Should I send multiple udp packets or use tcp?

Recommended Posts

I gather if I use udp I have to do the following, Create a realiable ack message system using in order packets so the files are recieved in order. Split big files up into multiple packets so they don't exceed the udp limit. Rejoin the packets the reciever side. If I use tcp can I do the following? Create tcp stream (Using sockets internally), and send one big file packet over the size of the file and it will be ensured to reach it's destination in order. Should I first send a 4 byte value indicating the size of the file so I know when it's been fully recieved? Also if udp is your suggestion, can someone please tell me the udp packet size limit? I've only heard about the limit, not what it actually is.

Share this post


Link to post
Share on other sites
I'd use TCP for that. It works the way you described.

Simulating TCP with UDP doesn't buy you anything in this case, to do better than TCP you would need to do some sophisticated stuff like using raptor codes. Advantage of raptor codes: some graphs

Edit:
The UDP packet size limit depends on the lower levels of the connection (Ethernet, wireless lan, whatever is used to actually transmit your packet), 1 UDP packet has to be delivered in one piece

[Edited by - Trap on June 7, 2006 2:51:06 PM]

Share this post


Link to post
Share on other sites
Yes, I'd use TCP for this. There's no benefit to using UDP if you need a large contiguous data block sending. Smaller, non-sequential deliveries suit UDP. Packet size limit varies, you can test for the largest allowable packet size:


// Create a normal UDP socket.
bool WSNormalSocket::createUDPNormalSocket()
{
if (m_bReady)
{
m_pLog->log("WSNormalSocket %x failed to createUDPNormalSocket - Socket already created!\n",this);
return false; // Socket already open!
}

m_sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
m_Protocol = WSSocket::WSSOCK_PROTO_UDP;

#ifdef WSCORE_WIN32
if (!m_sock)
#endif

#ifdef WSCORE_LINUX
if (m_sock==-1)
#endif
{
m_pLog->log("WSNormalSocket %x failed to createUDPNormalSocket - Could not create socket!\n",this);
return false;
}

unsigned int packSize;
int sz = sizeof(unsigned int);

WSNet& Net = WSNet::getSingleton();
if (Net.getSysMaxPacketSize()==0)
{
getsockopt(m_sock,SOL_SOCKET,SO_MAX_MSG_SIZE,(char*)&packSize,&sz);
Net.setSysMaxPacketSize(packSize);
};


m_pLog->log("WSNormalSocket %x created socket descriptor %d...\n",this,m_sock);
m_bReady = true;
return true;

};



Share this post


Link to post
Share on other sites
Quote:
The UDP packet size limit depends on the lower levels of the connection (Ethernet, wireless lan, whatever is used to actually transmit your packet), 1 UDP packet has to be delivered in one piece


That's not true. UDP can fragment over multiple IP fragments, and reassemble on the other end. Only if the "don't fragment" bit is set will it be delivered in a single piece.

However, if any one of the fragments don't make it within some time-out, the entire UDP datagram will be discarded on the receiving end, because the entire packet must be reassembled to be delivered -- it's "all or nothing" at the application layer.

Btw: TCP is the right solution for downloading map or patch files that are not part of the real-time data stream, assuming that you're not also trying to run a real-time data stream at the same time. If you're trying to also run the game on the same channel, you'll get in trouble where the TCP packets will cause UDP packet droppage and jitter.

Share this post


Link to post
Share on other sites
UDP can be a suitable mechanism for deploying files in a very small number of circumstances that probably don't apply to your application if it's anything like a normal game on a PC. For example, TFTP, a file transfer protocol that uses UDP, is used in a number of situations such as updating router firmware on routers without mass storage.

The best programming technique for transfering the file over TCP would depend on your networking API, the use for the file and/or programming language you are using. For example, if you use Java, it may be more suitable to use object serialization rather than raw file data to send the map information.

Additonally, it sounds like you want to transmit your file with a single call with TCP/IP. For most APIs, such as the sockets API, trying to send the entire file in a single send() call would be a mistake since send() may not actually send all the bytes in the buffer. It will return a value that indicates the number of bytes it actually did send. You'll probably need to feed successive chunks of the file with multiple send() calls.

Share this post


Link to post
Share on other sites
sendfile() will send a full file on a socket in a single call. Each OS has a variation of that call (there's also a WinSock version).

It's pretty much a way of putting a web server mostly into kernel space, for better performance. Some flavors even take iovec style pointers for prepending headers :-)

Share this post


Link to post
Share on other sites
You may find it more convenient to just send the URL of the resource and use HTTP to transfer the file.

That way you don't need to bother writing the server, you can just use an existing one. There are also lots of client libraries available, one of them is likely to be suitable.

Mark

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this