Sending / Recving Files over a socket

Discuss Programming
Post Reply
shuiend
scripter
scripter
Posts: 91
Joined: Mon Apr 28, 2003 8:05 pm

Sending / Recving Files over a socket

Post by shuiend » Wed Apr 21, 2004 9:05 am

How would I recieve a file from a socket? I can send it find and connect with telnet and it will show the file if it is text but how do i connect with a program and download it to a certain directory?

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Wed Apr 21, 2004 9:50 am

I have an *extremely* basic client server sample here:
http://voidmain.is-a-geek.net/files/socket/

You would have to come up with some sort of simple protocol (communication so each end knows when to start/stop/etc the file stransfer). On the client end you would save that data to disk. For a well refined example do an "apt-get source ftp" and dig around. :)

Tux
guru
guru
Posts: 689
Joined: Wed Jan 08, 2003 10:40 am

Post by Tux » Wed Apr 21, 2004 10:10 am

Would netcat work for you?

shuiend
scripter
scripter
Posts: 91
Joined: Mon Apr 28, 2003 8:05 pm

Post by shuiend » Fri Apr 23, 2004 9:54 am

Netcat dosent seem to do what i need so that is a no go. Voidmain the socket code you have was more or less what I already know howto do. I can send files over a socket and telnet in to see what the socket has already. So I know the send file works. I have been looking around on google but I can not find any information on how to get the file from the socket and output it to a folder. If i just put the binary file into a giant buffer on the client side could I then just save it to a normal file and still be able to run it? Any exaple code for something close to that would be nice. Also I am currently looking at the apt-get code and it is not helping me out alot.
My other idea was to just set up nfs folders on all the computers and do a syscall() and copy the files that way. They only problem is that there was no syscall for cp or anything that looked like it could copy the file.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Apr 23, 2004 10:39 am

First off, I assumed, and am still assuming that you are just doing this as a learning experience on how to do socket programming. If this is not the case, please stop me here. If you have some specific task in mind and are just trying to figure out how to do it then please fill me in on the entire thing, there probably is already a way to do what you need done.

Continuing on with the assumption that this is a learning project for socket programming and you want to know how to write something that will transfer files, sort of like wget or ftp or tftp, etc, then you need to come up with a protocol as I mentioned before. You need to have something on both ends that can talk to each other in a way that they each understand. For instance, wget is a "client" program that can communicate with an http or an ftp server. It is designed to use those protocols to tell the server end what it wants. If you want to design your server side from scratch, and you want to use an existing client (like wget, ftp, lynx, etc) then you'll need to write the server end to conform to that protocol standard. What I assume you want to do is to write both the client and the server side of things, and come up with your own protocol (shuiendtp - shuiend tranfer protocol) that is not ftp, http, etc. You want it to be simple, you want to be able to request a file from the server and have it saved on the client much like tftpd (server) and tftp (client).

If you think of tftpd and tftp as a simple (trivial) way to transfer files you will know that you have tftpd running on the server side. To download a file from it you use the tftp command. If you use that command interactively you might enter a commands like:

$ tftp yourserver.yourhouse.home
tftp> get somefile.txt

On your server you have "tftpd" running and it is assigned a certain directory to change into and serve files from. On the client you connect to that server process and you issued the command "get somefile.txt". Here's where the protocol comes in. The client knows that it needs to tell the server that it wants a file called "somefile.txt". The server will have to let the client know a few things before it sends it. Things like whether or not it has the file, if it does how big it is and when to start listening for it. Assuming the file exists the client starts waiting for data when the server says it is going to start sending it. As the client reads data from the socket it needs to write it to a file. If you are writing your code in C you might use the "fopen()" function to open the file and the "fwrite()" function to write data to the file as you grab it from the socket. Once you've received the specied amount of data you would close the file "fclose()". Obviously you'll probably want to add in error checking and timeouts etc etc.

Is this the sort of thing you are looking for? If so then looking at tftp/tftpd code might actually be helpful. Of course there are thousands of simple programs out there that transfer files across a network.

shuiend
scripter
scripter
Posts: 91
Joined: Mon Apr 28, 2003 8:05 pm

Post by shuiend » Fri Apr 23, 2004 1:04 pm

We are doing this as a school assignment and our project is to creat a parall-proccessing software. We have a head node and client nodes then 3rd party software that runs on top of it all. One of the requirements though installing and unistalling the 3rd party software with the head node onto all the client nodes. That is why i need to transfer the files. It will probally only be 1 binary file that i need to transfer but the program must be the thing doing it.

shuiend
scripter
scripter
Posts: 91
Joined: Mon Apr 28, 2003 8:05 pm

Post by shuiend » Wed Apr 28, 2004 2:09 pm

Well i got sending and recieving the file working hopefully. Now I have a question about the syscall() function. We need to be able to remove a file from a program. How would we do that? There is no syscall() function for rm. only for rmdir and i dont know how to use that so that you can remove all files inside the directory which would work. Or if there is another way to remove a file from a program that would be helpfull.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Wed Apr 28, 2004 2:36 pm

Normally if you want to delete files using native C you would use the "unlink()" function. Of course you can also cheat and do a system call:

system("/bin/rm -f /somedir/somfiles*");

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Mon May 24, 2004 5:06 pm

shuiend wrote:Well i got sending and recieving the file working hopefully. Now I have a question about the syscall() function. We need to be able to remove a file from a program. How would we do that? There is no syscall() function for rm. only for rmdir and i dont know how to use that so that you can remove all files inside the directory which would work. Or if there is another way to remove a file from a program that would be helpfull.
Well the rmdir() function only removes empty directories. so you would have to use the system() function or the exec() function anyways to remove the files before using rmdir(). Since that is the case you might as well use the system() call in the first place to remove the full directory.

The problem with unlink() is that it will not delete a directory unless you are root (or the program running the call is running as root) and even if this is the case unlink() has been known to cause damage to the filesystem so use at your own risk.

Your best bet would be to use exec() or system() to remove a full directory if this is what you want to do. If you simply want to remove some files inside a directory but leave the directory then unlink() will work fine for you. The difference between exec() and system() is that exec() will NOT return anything such as status values and system() will return a status value (0 or 1) depending on if the command was executed successfully or not.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Mon May 24, 2004 6:38 pm

As I said, using exec/system is "cheating". If you wanted to do it in native C you would use unlink() and/or rmdir(). For directories you use the rmdir() function. You do not have to be root to remove a directory. I would be interested in where you came up with all of that. Download the source for the base system commands such as "rm" and "rmdir" and I think you'll find that they use the "unlink()" and "rmdir()" functions. I don't know how else you would do it as there are no other C functions that I am aware of for doing this.

Most good C programmers would frown on cheating with system calls for several reasons. Why call a system command when the system command is going to do the same thing you would do with unlink()/rmdir()? It introduces possible security issues, possible memory issues, it has to spawn a child process, have to assume the location of the command or write code to search for it, etc, etc.

$ man 2 unlink
$ man 2 rmdir
$ man 2 remove

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Mon May 24, 2004 10:17 pm

Most good C programmers would frown on cheating with system calls for several reasons. Why call a system command when the system command is going to do the same thing you would do with unlink()/rmdir()? It introduces possible security issues, possible memory issues, it has to spawn a child process, have to assume the location of the command or write code to search for it, etc, etc.
Also can be platform specific which no good C program should be :) .

As far as being root to use unlink() function, this is the way Perl is and the way C is on some systems.

[root@Hackbox root]# info unlink
On some systems `unlink' can be used to delete the name of a
directory. On others, it can be used that way only by a privileged
user.
In the GNU system `unlink' can never delete the name of a
directory.
Oh and you can also use remove() function but this function simply uses the unlink() function for files and the rmdir() function for directories.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Mon May 24, 2004 10:31 pm

ZiaTioN wrote:As far as being root to use unlink() function, this is the way Perl is and the way C is on some systems.
Since when? I use unlink in my Perl programs all over the place and never run any of them as root, besides the fact that we weren't talking about Perl. :) I have never seen this be the case in C either. I would certainly be interested in seeing an example of such systems. The only place root should be required to unlink a file is if the file has permissions set where a user wouldn't be able to "rm" it either.
On some systems `unlink' can be used to delete the name of a
directory. On others, it can be used that way only by a privileged
user.
In the GNU system `unlink' can never delete the name of a
directory.
Here it says you could use unlink to remove a "directory" on some systems, but only as root. That's not really what I was suggesting. I said to use unlink() for files and rmdir() for directories which I would think would be pretty much the standard.
Oh and you can also use remove() function but this function simply uses the unlink() function for files and the rmdir() function for directories.
That's why I quoted the man page on the remove() function in my previous message. :)

Post Reply