Re: Socket read problem
From: James Antill (james-netnews_at_and.org)
Date: 08/30/04
- Next message: Jens.Toerring_at_physik.fu-berlin.de: "Re: select () on pseudo-terminal"
- Previous message: cherico: "select () on pseudo-terminal"
- In reply to: Matta: "Socket read problem"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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/
- Next message: Jens.Toerring_at_physik.fu-berlin.de: "Re: select () on pseudo-terminal"
- Previous message: cherico: "select () on pseudo-terminal"
- In reply to: Matta: "Socket read problem"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|