I had a situation where i have to transfer one or many files from 30 differrent clients to one server.
The problem I was facing with is multiplexing while at the same time sending the file name and then the contents of the file ...
I came up with this code with the help of a colleague... it is helpful for files which are in KBs... , but if you were to transfer files whose size were in MBs, then the server might not listen , if its busy listening to other clients...(considering the number of clients are many..)

Please feel free to make any changes and do let me know in case you have a better one!
Thanks!

Server... #!c:\perl\bin\perl.exe use strict; use IO::Select; use IO::Socket; my ($filename,$new, $fh, @ready); print "Listening to sockets on port 8080\n"; my $lsn = IO::Socket::INET->new( Listen => 1, LocalAddr => 'localhost', LocalPort => 8080, ) or die "Can't create server socket: $!"; my $sel = new IO::Select( $lsn ); #can_read -> Return an array of handles that are ready for reading. while(@ready = $sel->can_read) { foreach $fh (@ready) { if($fh == $lsn) { # Create a new socket $new = $lsn->accept; $sel->add($new); print "Created a new socket $new\n"; } else { # Process socket print "processing socket $lsn\n"; $filename=<$fh>; print "trying to open file $filename"; open FILE, ">$filename" or die "Can't open: $!"; while (<$fh>) { print FILE $_; } close FILE; # Maybe we have finished with the socket $sel->remove($fh); $fh->close; } } } Client: #!c:\perl\bin\perl.exe use strict; use IO::Socket; use Cwd; my $pwdr=cwd; my $appchoice; my ($res, $sockpass); sub client_connect ($$) { my $peer_addr=shift; my $server = IO::Socket::INET->new(Proto => "tcp", PeerPort => 8080, PeerAddr => "$peer_addr", Timeout => 2000) || die "failed to connect to the server\n"; open FILE, "<full path of filename>" or die"Error: $!\n"; print $server "ivr\n"; while (<FILE>) { print $_; print $server $_; } close FILE; } my $message="hello"; client_connect("localhost","$message");

Replies are listed 'Best First'.
Re: Client(s) sending file(s) to server using Sockets
by zentara (Cardinal) on Jan 23, 2004 at 15:42 UTC
    You might want to look at this Sockets-file-upload-w-EasyTCP

    It has a port password and optional encryption of files. The Net::EasyTCP module has been improved since I wrote this script, so you can do:

    my @nocrypt = qw(Crypt::RSA); #too slow, but more secure my $server = new Net::EasyTCP( host => "$host", mode => "server", port => "$port", # donotencrypt => 1, donotencryptwith => \@nocrypt, password => "$portpassword", ) || die "ERROR CREATING SERVER: $@\n";
Re: Client(s) sending file(s) to server using Sockets
by b10m (Vicar) on Jan 23, 2004 at 12:36 UTC

    Couple of things:

    First of all, you use port 8080 for this daemon, which strikes me slightly as odd. Of course you are free to use any port available, but port 8080 is usually used as an alternative for HTTP.

    Secondly, I miss authentication/security ;) This daemon -as I see it- allows connections from everywhere and is ok with the idea that the client is giving the filename. I don't know much about the win32 OS (which you seem to use), but imagine this on a *NIX machine and I decide to upload some text file with a filename of "/etc/passwd" and "/etc/shadow". (Ok, true enough, running this daemon as root is stupid to begin with ;) I'm sure there are files on your OS that you'd rather see not updated by the clients. Using authentication at least gives you someone to blame when things go ugly, and of course, please do check the filename input.

    Finally, have you considered the already available alternatives, such as ftp, sftp/scp, rsync (does that exist on win32?)? You could even write an upload CGI script, and let your http daemon "handle" the connections.

    Just my €0.02

    --
    b10m
Re: Client(s) sending file(s) to server using Sockets
by bageler (Hermit) on Feb 27, 2004 at 05:33 UTC
    I'm curious why ftp or scp are unacceptable solutions? If the need is for some sort of pre or post processing, proftpd will let you log transfers to pipes...where I usually put a perl script to do fancy stuff like inserting things into a database or handle segmented uploads.