Getting specific chunk of data from file on FTP server - c

I am writing FTP client in C. I am not making any changes to Server program.
I want to get specific amount of data from a file on server.
Suppose I have a file on server and I want to read last 100 bytes from the file. I don't want to read whole file.
I am able to get whole file using
RETR filename but I didn't find any way to read specific amount of bytes.
Is there any way to do this for a standard FTP server?

Is there any way to do this for a standard FTP server?
No. You can tell the server the position where it should start with the REST (restart) command, but you cannot tell it how much data it should send. All you can do is close the data channel after you've received the amount of data you want. The FTP server will probably complain about this because it received a RST (writing against a closed socket) but in most cases this should not cause problems.

Related

Requesting size of Stream from consumer, before loading all the data

Hy all,
I have a problem with the camel component I am developing, where I'm not sure how to implement it in a way, that goes in line with the concepts of camel.
The producer I'm developing talks to the http api for our server, which is used to send messages with attachments.
Those attachments can potentially be very big, which is why the server expects the total filesize before any upload is done.
Currently the producer only accepts io.Files, nio.Paths and GenericFile, because there I can read the file size, before I upload the file.
Of course this is not a good way to do things, because it requires the (big) file to be available locally.
Connecting, for a example, a ftp server as the consumer would mean, that I have to download each file locally so I can upload it afterwards.
The obvious solution is using streams to access and upload the data, but with this I do not know how big the file is, before I'm done uploading, which is not an option, I need the size in advance.
My question now is, what are best practices to stream files through camel and also make the consumer give me the filesize in advance.
Greets
Chris
For File/FTP consumer, the exchange in header has a key CamelFileLength (Exchange.FILE_LENGTH) which return the file size in remote ftp server from consumer's scan result.
Unlike the file size obtain from local, the file size in key CamelFileLength might differ from actual file size your application received
The ASCII mode will potentially change the linefeed when there is OS differ
The file size might change between consumer scan action and consumer pick actionn

Do I need to check data integrity after sending file over ftp?

I need to transfer some files from remote computer (on local network) and I plan to do it via FTP.
Apparently, FTP is based on TCP protocol and if I remember well my lessons the difference between TCP and UDP is that TCP checks that network packets are correctly send and received.
After asking myself if I need to add checksum verification, my conclusion was that I don't need to. Am I correct ?
I'm aware of the differences between binary transfer and text transfer and plan to do only binary transfers (working only on Windows).
Do I really need to checksum big files transfered by binary FTP ?
Be it clear, I need data integrity to verify that some bits where not altered during the exchange. Man in the middle is not (much) an issue because the operation will be done in a private network.
Yes, you do.
A man in the middle can alter any TCP packets on the way from the ftp server to your site or he can even act as a malicious ftp site and suppress the original traffic completely.
Therefore you need to verify somehow that that file you received is really the file you wanted to receive. Checksums are suitable for this task.

using client server text chat to provide audio support

I have implemented a multiple client-server text chat in c over Linux(using TCP sockets). Now i want to use it to support audio files as well.After going through stack overflow i found that this can be achieved by sending a file from client to server and server sending same file to all clients.
Now my question is
how can the server(and clients) differentiate whether it is receiving ordinary text data or (the server)has to pack the receiving data into a file?
Also till now what i have is that client enters text and the server receives it.How can i provide an option to client to send either a file or text.I was thinking of using switch case(like 1 for file ,2 for text) but that is not a good interface?
You have two questions here.
For 1: You will need to decide how they differentiate text data from file data, by sending extra bytes. One possible scheme is the following:
For chat messages:
Send the byte 1 (meaning this is a chat message).
Send the message.
Send a \n.
For files:
Send the byte 2 (meaning this is a file).
Send the length of the file, as an 8-byte integer.
Send the file contents.
For 2: That is also up to you. I would suggest that your client works the same way it does already (anything the user types is a chat message) unless the user types a special command, like "/file". If the user types the command, then the client can ask the user for which file to send, and send it.
I suggest you use an industry-standard way of representing different part types. Have a look at MIME encoding. Your normal messages would be in (e.g.) text/plain. This is (broadly) how HTTP determines what to do with the byte-stream it receives from the server.

Best way to write a ftp client program to list files on the server?

I am trying to write a client-server program in C in windows. The objective is to receive the directory listing from the server. Now I was trying to develop the client-server in such a way to utilize most resources.
One way to implement is that server makes a single send() call to send info of a single file. So if there are 100 files, it makes 100 calls. But I feel its a wastage of network resources. As far as I know the buffer size for send() or recv() in windows is 8kb. But the info of a single file will be hardly 1kb. So is there a way to make send() call to send multiple files info (file info are stored in structures. So they basically form a linked list) ? May be I can send info of atleast 8 files in a single Send() call. That should reduce the total send() calls to maximum 13.
So basically is there a way to send a linked list via send() ?? Plz let me know if you can think of any alternative method.
Good question! +1 for that.
But do you really want or need to write your code to use Winsock? There are good reasons to do so -- including that it's fun and a challenge. But if you don't need to, you might want to consider using the libcurl ftp library, which is free, multi-platform (including win32, of course), just works, and might make your job a lot easier.
The only way I know of to do this with FTP is to use multiple connections to the FTP server. If this is allowed by the server, there can be a list performance boost because the many protocol exchanges needed to list a complete folder tree can be run in parallel.
Rgds,
Martin
TCP is a byte stream. There is no guarantee of a 1-to-1 relation between the number of items you want to send and the number of calls to send() (or recv()) you need to make. That is simply not how TCP works. You format the data the way you need to, and then you keep calling send() until it tells you that all of the data has been sent.
Regarding FTP, please read RFC 959 and RFC 3659 to learn how the ftp protocol actually works. Before the introduction of the MLST and MLSD commands, directory listings had no standardized format. FTP servers were free to use whatever formatting they wanted. Many servers just piped the raw data from the OS's own dir or list commands. Indy, for example, includes several dozen parsers in its FTP client for handling non-standard directory listings.

querying multiple servers

I am building a web service which needs to query 1 to n file servers, and receive multiple files as a result. Does anyone have a good idea on doing this? Would Threads do any good job?
What if the connection with some servers takes longer than the others? How do I know if I really have ALL the queried files?
Thanks
Your question is quite generic and so will be my answer, anyway I hope it will be useful.
I would say you have two options here:
Use an asynchronous model. You open the connections to the N file servers, and set up a callback (or an event) that will fire whenever data from one server is received (usually these callbacks will be invoked in a new thread, but check the documentation for your working framework). You get the connection identifier from the data passed to the callback/event, and update the appropriate file.
Use a syncrhonous polling model. You open the connections to the N file servers, and enter a loop in which you poll each connection for new data; when new data is available, you update the appropriate file. You exit the loop when all files are completely downloaded.
As per how you know when all files are complete, there is no automatic way for that. You need to establish a convention, known by both you and the server, as to how to know that a file has been completely sent. Options include: the server closes the connection when the file is complete (not very safe as the connection can be accidentally closed), the server sends the file size prior to the file contents, and the end of file is signaled by a special character sequence (this works better on text files where the bytes of the end of file sequence will not normally occur).

Resources