Re: Socket read problem

From: James Antill (james-netnews_at_and.org)
Date: 08/30/04


Date: Mon, 30 Aug 2004 13:22:11 -0400

On Sat, 28 Aug 2004 12:16:42 +0300, Matta wrote:

> Hi,
>
> I'm writing an NNTP based program that downloads articles from Usenet.
> I've run into a weird problem. It seems as if there is a bug somewhere
> that causes certain articles to download incorrectly (just by a byte or
> two). It happens to the same articles and about 1 out of 5 have issues. So
> everything seems to work ok, but somewhere something causes this weird
> behavior.
>
> The code that should work but doesn't (sometimes) downloads an article and
> returns it.
>
> Any help would be appreciated. What would be the "right" way to read the
> data from the socket?

 Well C++ isn't something I've used much. But...

> Matta
>
> - - - - -
>
> string NNTP::net_recv()
> {
> int numbytes;
> string buffer;
> char buf[MAXDATASIZE];
>
> numbytes = recv(sockfd, buf, MAXDATASIZE-1, 0);

 You are just ignoring the error when connection closes etc. This is bad.

> if (numbytes < 1) {
> return "";
> }
>
> buf[numbytes] = '\0';
>
> buffer = buf;
> return buffer;
> }
>
> extern "C" string NNTP::get_article(string msgid) {
> string rdata, sendstr, tmp;
> string::size_type pos;
>
> sendstr = "ARTICLE ";
> sendstr += msgid;
> sendstr += "\r\n";
>
> net_send(sendstr);
>
> rdata = "";
> do {
> rdata += net_recv();
> } while (rdata.substr(rdata.length()-5, 5) != "\r\n.\r\n");

 Think about what happens if rdata.length() < 5.

> rdata = rdata.substr(0, rdata.length() - 3);
>
> pos = rdata.find("\r\n\r\n", 0);
> rdata = rdata.substr(pos + 4, rdata.length() - (pos + 4));

 I assume this is trying to find the end of the headers? And remove them?
personally I'd still check for string::npos.
 Also if you do...

         rdata = rdata.substr(pos + 4, string::npos);

...it defaults to from point X to the end of the string ... and that's the
default if the second parameter isn't passed.

> if (rdata.substr(0, 2) == "..") {
> rdata.erase(0, 1);
> }
>
> pos = 0;
> while ((pos = rdata.find("\r\n..", pos)) != string::npos) {
> rdata.erase(pos + 2, 1);
> }

 This looks ok, although I'd have merged the if and the while.

> return rdata;
> }

-- 
James Antill -- james@and.org
Need an efficient and powerful string library for C?
http://www.and.org/vstr/


Relevant Pages

  • Re: FTP, HTTP file transfers
    ... Downloads and uploads over http can be accomplished using the WebClient ... Find great Windows Forms articles in Windows Forms Tips and Tricks ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Socket read problem
    ... > I'm writing an NNTP based program that downloads articles from Usenet. ... > string rdata, sendstr, tmp; ...
    (comp.unix.programmer)
  • Re: Disconnection During Music Download
    ... don't mind paying for my downloads but, to be honest with you, I'm not sure what site to use. ... I've read several articles on the Internet that say a lot of sites that charge consumers are simply offering programs that are available for free. ... personal choice which you would like better. ...
    (microsoft.public.windowsxp.music)
  • Socket read problem
    ... I'm writing an NNTP based program that downloads articles from Usenet. ... It seems as if there is a bug somewhere ...
    (comp.unix.programmer)
  • Socket reading problem
    ... I'm writing an NNTP based program that downloads articles from Usenet. ... It seems as if there is a bug somewhere ...
    (comp.lang.c)