mIRC Home    About    Download    Register    News    Help

Print Thread
Download file through socket #204359 16/09/08 11:36 PM
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
I'm trying to have my socket download an image file from a site.

I only get a file which is <100 bytes with content like...

Quote:
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz


Here's my code...

Code:
on *:SOCKOPEN:chansock:{
  sockwrite -n $sockname GET / $+ $gettok(%chan.url,3-,47) HTTP/1.1
  sockwrite -n $sockname Host: %chan.host
  sockwrite -n $sockname Accept: */*
  sockwrite -n $sockname Connection: keep-alive
  sockwrite -n $sockname User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)
  sockwrite -n $sockname $crlf
}

on *:SOCKREAD:chansock:{
  if ($sockerr) {
    return
  }
  else {
    var %chan.data
    sockread %chan.data
    while ($sockbr) {
      sockread %chan.data
    }
    sockread -f %chan.data
    if (*404 not found* iswm %chan.data) {
      msg %chan.chan Error: 404
      sockclose chansock
      unset %chan.*
    }
    else {
      bwrite %chan.file -1 -1 %chan.data
      msg %chan.chan Succeed!
      sockclose chansock
      unset %chan.*
    }
  }
}

Last edited by gaui; 16/09/08 11:36 PM.

__________________________
Curiosity killed the cat.
Re: Download file through socket [Re: gaui] #204360 17/09/08 12:09 AM
Joined: Aug 2004
Posts: 7,252
R
RusselB Offline
Hoopy frood
Offline
Hoopy frood
R
Joined: Aug 2004
Posts: 7,252
I haven't done much with sockets, but I seem to recall someone else having a similar problem (on a different site), and they were advised to use binary variables, rather than local/global variables to store the information.

I'll see if I can find the topic again and post more details or a link to the topic.

Re: Download file through socket [Re: RusselB] #204371 17/09/08 11:28 AM
Joined: Jun 2008
Posts: 58
P
Pivo Offline
Babel fish
Offline
Babel fish
P
Joined: Jun 2008
Posts: 58
There have been some threads on a german mirc-scripting board, which I've made a sample code for (maybe a year ago...)
There isn't that much to explain, I used binary variables and file handling...

Code:
alias down {
  if ($sock(down)) { return }
  sockopen down $1 80
  sockmark down $2-
}
on *:sockopen:down: {
  if ($sockerr) { return }
  var %s = sockwrite -n $sockname, %f = $sock($sockname).mark
  sockmark $sockname
  .fopen -o down $qt($gettok(%f,-1,47))

  %s GET %f HTTP/1.1
  %s Host: $sock($sockname).addr
  %s User-Agent: mIRC $version
  %s Connection: close
  %s $crlf
}
on *:sockread:down: {
  if ($sockerr > 0) { return }
  if ($sock($sockname).mark == 1) { goto download }

  var %s
  sockread %s
  while ($sockbr > 0) {
    if (%s == $null) {
      sockmark $sockname 1
      return
    }
    sockread %s
  }
  return

  :download
  var &s
  sockread &s
  while ($sockbr > 0) {
    .fwrite -b down &s
    sockread &s
  }
}
on *:sockclose:down: {
  .fclose down
  echo -agt Download finished.
}


/down host.name.net /path/to/the/file.jpg

Example:
/down mirc.cachefly.net /images/indexlogo.gif
Will download http://mirc.cachefly.net/images/indexlogo.gif ...

Don't know if my method is clear, but I can't really think of something worth to explain...
So just ask if there's something strange.
(Why did I use goto? - Don't know... I think it suits fine in this case :P
Yes, there are also missing some checks like 'does the file exist?', but it's just an example...
Paths and so on should be easy to change.)

Edit:

Well.. first I was saving the download-path with sockmark.
At the sockopen, I save the $sockmark value to a local variable first, to use it in the header later.
I clear sockmark and open the file I'm trying to write right into.
Sending the header and waiting for reply...

The sockread event checks for errors first...
After that, it consists of 2 parts.
The first one is for the header...
After the header, there's always following an empty line.
When this line comes, $sockmark is being filled with "1" to tell the script, it should goto download...
It does, thats the 2nd part, which writes the data to the file.

Last edited by Pivo; 17/09/08 11:45 AM.
Re: Download file through socket [Re: gaui] #204373 17/09/08 02:12 PM
Joined: Apr 2003
Posts: 61
G
gaui Offline OP
Babel fish
OP Offline
Babel fish
G
Joined: Apr 2003
Posts: 61
Thanks, but what am I doing wrong?


__________________________
Curiosity killed the cat.
Re: Download file through socket [Re: gaui] #204375 17/09/08 04:23 PM
Joined: Jun 2008
Posts: 58
P
Pivo Offline
Babel fish
Offline
Babel fish
P
Joined: Jun 2008
Posts: 58
Well.. your main problem may be that part:
Code:
    sockread %chan.data
    while ($sockbr) {
      sockread %chan.data
    }

That means that you execute /sockread until there's nothing left in your in-buffer...
/sockread reads only 1 line out of the buffer, and it can also hold only 1 line in your variable.
That means that %chan.data will only hold the last line of the buffer after that code.

All your code that works with the page-source must be inside this while-block.
You could also use the goto-method as shown in the example in the mirc help - /help /sockread

Additionally, after this problem is fixed, your script will try to use bwrite with %chan.data - which is not a binary variable!
I'm not sure if it's really necessary - but I recommend to use binvars to download files...

And also.. you will have the http-header inside the file-data, which breaks the file.

Last edited by Pivo; 17/09/08 04:48 PM.