Transfering file on UDP socket in C! Linux - c

I'm programming an application for transferring a file between two host with an UDP socket.
But it seems that some data arrives corrupted at the client.
My question is: is it possible that if the server is faster than the client, the client could read corrupted data from the socket?
I use sendto() in the server and read() in the client (I use the connect() before beginning transferring the file in the client),
and if yes: how can I stop the server from sending new data until the client has read all the previous data?

is it possible that if the server is faster than the client, the
client could read corrupted data from the socket?
No it is not possible - every datagram that you see is error checked by the IP layer and will be as it was sent.
how can I stop the server from sending new data until the client has
read all the previous data?
Typically you send a small packet, the receiver sends an acknowledgement, then you send the next. Problem with UDP however is packets can get dropped without telling you event duplicated moreover you can flood the network as there is no congestion control..
So why re-invent the wheel, use TCP for sending files which takes care of reliability and congestion control - everyone has been using that for decades, e.g. this web page is delivered to you using HTTP which uses TCP.

Related

C LINUX\WINSOCK- check FIN packet in Send

I am trying to understand how to avoid the following scenario:
A client kills its process. A FIN message is sent to server.
Server receives the FIN message from the client.
A milisecond after the server receives the FIN message, the server uses the send message, and sends information to the client.
Using the C API- can the server know what packets are acknowledged by the client?
If so- what are the commands in Linux\Winsock?
This question comes up periodically. Short answer: The TCP layer in the OS intentionally does not pass up "acks" (acknowledgement of receipt) to the application layer. And if it did, it would be the rope you would hang yourself by. While TCP is considered "reliable", it doesn't actually have a way to indicate if the application code above it has actually processed the received bytes.
You mentioned "packets", but that is a very ambiguous term. Your socket application may have the notion of "messages" (not packets), but TCP does not have the concept of a packet or even a message. It sends byte "streams" that originate from your application code. TCP segmentation, IP fragmentation, and other factors will split your message up into multiple packets on the wire. And TCP has no knowledge of what IP packets make up the entire application message. (Common socket fallacy - many developers erroneously believe a "send" corresponds to an identically sized "recv" on the other side).
So the only code that can acknowledge success receipt of a message is the socket application itself. In other words, your client/server protocol should have its own system of acknowledgements.
I can't speak for Linux, but under Windows if a process is killed with established connections open, those connections are forcibly (hard) reset. The peer will receive a RST, not a FIN, and further communication over the connection is impossible.

TCP in C Programming

I want to know how a client or server gets an acknowledgement packet from a client or server after sending a packet in TCP Channel in C programming.
Why don't I need to handle this in code? How exactly does the client receive the acknowledgement packet, if it sends a data packet to server? Does this happen internally?
The TCP protocol is designed to provide a stream protocol. The typical programming interface is the socket interface where you can give a chunk of data that the protocol stack will transfer to the receiver. The actual implementation hides when the data has been queued in the receiving protocol stack or has been handed off to the receiving application. You would have make this distinction.
Sou what you apparently want is a signal mechanism to know, that and when the client has read the data from the protocol stack. This can be done by designing and implementing a protocol on top of the TCP protocol. When one side doesn't have to send meaningful data it sends a heartbeat message. This message indicates that the TCP connection is still alive.
Regarding your questions:
Why don't I need to handle this in code? Because the underlying layer has it done for your.
How exactly does the client receive the acknowledgement packet, if it sends a data packet to server? You don't need to care as long as you don't need a heartbeat. TCP provides you a stream interface similar like the interface for file I/O. You don't ask, when the data has left the disk cache, do you? When you start to re-implement internas you will have to define what about reassemblies, Nagle-algorithm and many other nasty things. Never implement TCP if you have another choice.
Does this happen internally? Yes, fortunately.

Two-way communication in socket programming using C

I have a small doubt in socket programming. i am able to send my data from client to server and my server processes the data. The o/p of the data processed, I want to send back to my client. So can we "write" the data back to the client using the same socket. I mean a server listens on a port before accepting connection and receiving data, so similarly, do i need to make my client listen to some other port (bind it some other socket) and make my server connect to that socket and transfer the data back. Any kind of example or explanation or references would be appreciated. Thanks a lot in advance.
Check out Beej's Network Programming Guide first of all.
The basic screenplay of a server/client connection goes like this:
Server listen()s on a fixed port, with a given socket.
Client connect()s to a the server port; client obtains a socket.
Server accept()s the connection, and accept() returns a new socket for the connection.
(Server continues listening on the original port with the original socket.)
For the specific connection with the client, the server write()s to the new socket it obtained when accept()ing the incoming connection. A busy server will have many, many sockets, but it will only ever need to bind() to one port. All connections come in to that one port, but the OS's networking protocol stack separates the data and makes it available at the connection-specific socket.
You don't need a new socket.
A socket is a duplex connection you can send data in both directions and you can even close the socket from one direction (don't want to write anymore) but still send data from the other direction.
Your socket is bi-directional, so there is no need to create another socket. Unless you are using some sort of middleware, such as Pub/Sub, there is no need to create another socket to enable bi-directional communication.
Technically it is right, the socket is duplex and you can send the data to the same socket you read from:
SOCKET s = socket()
... //Connect
int size = receive(s,...);
//make response
send(s, ...);
But in practice it depends on what are you going to do. It is possible to hang out socket if you have the following situation:
Process 1 sends very big data (<100K) over the socket by one send
operation
Process 2 receives data from 1 by portions and sends small packets to 1 (~20b). It is not a
confirmations, but some external events.
The situation goes into hangout, where the sending buffer of the 2 is full and it stops sending confirmations to 1.
2 and 1 are hanging in their send operations making a deadlock.
In this case I'd recommend using two sockets. One for read, one for write.
(Late answer, so mainly for anyone else who comes here looking for help)
I recently put up an example client/server application that closely follows Beej's Guide to Network Programming (which was also recommended by Kerrek SB in his answer). If you're looking for a simple working example of client/server communication, maybe this will help:
https://github.com/countvajhula/dummyclientserver
In particular, no, your client does not need to set up a separate listening socket to receive data from the server -- after the server has accepted the connection from the client, the server can simply send data back to the client on the same socket.

A file server and its associated clients

I am extremely new to socket programming and I am implementaing a file server that receives request like open(), read(), write(), close() from clients. The file server will process the requests and send the clients the return value of each system call.
I don't know what type of socket I need to define(i.e. stream socket, datagram socket etc). and what command will send the request from the client, how will I receive the return value from the server, how will I receive it at the server end and send the return value to my client.
Will be gratefull to get some pointers.
Thanks
An edit: Is something simple like this work for starting Server not able to properly read/open a filename sent by client in C
It depends in part upon your file server design.
If you're going for a stateless server, then datagram or stream would be fine. Datagram is relatively nice because your servers and clients don't need to handle partial requests -- the entire contents of the request are contained in the datagram.
If you're going for a stateful server, then stream might be nicer -- you can automatically release locks and de-allocate resources 'owned' by a client when you receive a TCP RST packet. (Client gone, throw away their state.) You could of course build a stateful server with datagram services, but it doesn't seem like a good fit.
But on the open Internet, typically you have just UDP and TCP -- I have no idea if RDP, a reliable datagram transport, is routed on given ISPs or not. And being forced between unreliable datagrams and reliable streams, I'd recommend reliable streams almost every time. Will your use your protocol on reliable LANs only? Or on lossy wireless or public Internet links?
I would use a streaming socket, but others have done differently, for example the Network File System (NFS).
To communicate between a client and the server you need a protocol. The one that OpenSSH uses for their scp and sftp programs is nice to implement. Have a look at it. http://openssh.org/txt/draft-ietf-secsh-filexfer-02.txt

Is there a way to tell the OS to drop any buffered outgoing TCP data?

I've got an amusing/annoying situation in my TCP-based client software, and it goes like this:
my client process is running on a laptop, and it is connected via TCP to my server process (which runs on another machine across the LAN)
irresponsible user pulls the Ethernet cable out of his laptop while the client is transmitting TCP data
client process continues calling send() with some additional TCP data, filling up the OS's SO_SNDBUF buffer, until...
the client process is notified (via MacOS/X's SCDynamicStoreCallback feature) that the ethernet interface is down, and responds by calling close() on its TCP socket
two to five seconds pass...
user plugs the Ethernet cable back in
the client process is notified that the interface is back up, and reconnects automatically to the server
That all works pretty well... except that there is often also an unwanted step 8, which is this:
.8. The TCP socket that was close()'d in step 4 recovers(!) and sends the remainder of the data that was in the kernel's outbound-data buffer for that socket. This happens because the OS tries to deliver all of the outbound TCP data before freeing the socket... usually a good thing, but in this case I'd prefer that that didn't happen.
So, the question is, is there a way to tell the TCP layer to drop the data in its SO_SNDBUF? If so, I could make that call just before close()-ing the dead socket in step 4, and I wouldn't have to worry about zombie data from the old socket arriving at the server after the old socket was abandoned.
This (data recieved from two different TCP connections is not ordered with respect to each other) is a fundamental property of TCP/IP. You shouldn't try and work around it by clearing the send buffer - this is fragile. Instead, you should fix the application to handle this eventuality at the application layer.
For example, if you recieve a new connection on the server side from a client that you believe is already connected, you should probably drop the existing connection.
Additionally, step 4 of the process is a bit dubious. Really, you should just wait until TCP reports an error (or an application-level timeout occurs on the connection) - as you've noticed, TCP will recover if the physical disconnection is only a brief one.
If you want to discard any data that is awaiting transmission when you close the socket at step 4 then simply set SO_LINGER to 0 before closing.

Resources