Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #10057 > unrolled thread

Small tcp client for review

Started byRam Prasad <ramprasad.ap@gmail.com>
First post2011-09-09 10:46 -0700
Last post2011-09-10 08:25 +0100
Articles 7 — 6 participants

Back to article view | Back to comp.lang.c


Contents

  Small tcp client for review Ram  Prasad <ramprasad.ap@gmail.com> - 2011-09-09 10:46 -0700
    Re: Small tcp client for review Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-09 20:44 +0100
    Re: Small tcp client for review Gene <gene.ressler@gmail.com> - 2011-09-09 13:43 -0700
      Re: Small tcp client for review Ram  Prasad <ramprasad.ap@gmail.com> - 2011-09-09 23:02 -0700
        Re: Small tcp client for review Ralph Spitzner <rasp@spitzner.org> - 2011-09-10 08:40 +0200
        Re: Small tcp client for review Seebs <usenet-nospam@seebs.net> - 2011-09-13 06:44 +0000
    Re: Small tcp client for review Nobody <nobody@nowhere.com> - 2011-09-10 08:25 +0100

#10057 — Small tcp client for review

FromRam Prasad <ramprasad.ap@gmail.com>
Date2011-09-09 10:46 -0700
SubjectSmall tcp client for review
Message-ID<d9a9b4b9-9a5e-4107-b518-a13904e69021@g19g2000prf.googlegroups.com>
I am a perl programmer , need to write a small tcp client in C to pass
the input to a perl Daemon
This is going to be a very high volume application , So I better make
sure the code is efficient enough.

I have written a program (googled for it ) borrowed from Paul Griffith
site
But I dont know if this is a "good" code. Can someone please review
this for me

http://pastebin.com/Arqr129B


Thanks
Ram

[toc] | [next] | [standalone]


#10059

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-09-09 20:44 +0100
Message-ID<0.3cc708550691f828b40c.20110909204445BST.87aaad33gy.fsf@bsb.me.uk>
In reply to#10057
Ram  Prasad <ramprasad.ap@gmail.com> writes:

> I am a perl programmer , need to write a small tcp client in C to pass
> the input to a perl Daemon
> This is going to be a very high volume application , So I better make
> sure the code is efficient enough.

Why not a Perl program?  Do you know that it won't be fast enough?

> I have written a program (googled for it ) borrowed from Paul Griffith
> site
> But I dont know if this is a "good" code. Can someone please review
> this for me
>
> http://pastebin.com/Arqr129B

It's short so you could have posted it but if there are issues they will
be to do with the networking so this is not the right group.
comp.unix.programmer would be good.

Given that the code just copies its input to a socket, you could just
use a pre-existing tool like netcat.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10060

FromGene <gene.ressler@gmail.com>
Date2011-09-09 13:43 -0700
Message-ID<8c91b24f-a4c2-4572-8e45-c0d1ce627ef8@eb1g2000vbb.googlegroups.com>
In reply to#10057
On Sep 9, 7:46 pm, Ram  Prasad <ramprasad...@gmail.com> wrote:
> I am a perl programmer , need to write a small tcp client in C to pass
> the input to a perl Daemon
> This is going to be a very high volume application , So I better make
> sure the code is efficient enough.

It's hard to imagine why you wouldn't use Perl's built-in TCP
support.  There's an entire O'Reilly book on this topic.

[toc] | [prev] | [next] | [standalone]


#10082

FromRam Prasad <ramprasad.ap@gmail.com>
Date2011-09-09 23:02 -0700
Message-ID<fe2d0e7c-e924-4bf8-a9cf-5e82e2ba177e@a14g2000prl.googlegroups.com>
In reply to#10060
On Sep 10, 1:43 am, Gene <gene.ress...@gmail.com> wrote:
> On Sep 9, 7:46 pm, Ram  Prasad <ramprasad...@gmail.com> wrote:
>
> > I am a perl programmer , need to write a small tcp client in C to pass
> > the input to a perl Daemon
> > This is going to be a very high volume application , So I better make
> > sure the code is efficient enough.
>
> It's hard to imagine why you wouldn't use Perl's built-in TCP
> support.  There's an entire O'Reilly book on this topic.

Because if I use a perl program  there will be a perl script forked
everytime when called.
Much worse than executing a c binary client program.


This is a part of a mailing system , which receives upto 100k mails an
hour

Currently mail reaches postfix , postfix calls a perl script and does
the processing , looking for particular strings using regex and
But the things are not quick enough.


This is not my original idea :-).  Like spamc is used as a small tcp
client to talk to spamd for antispam spamassassin scanning.



This is the code

 /*
 * Most of the code is from http://www.paulgriffiths.net/program/c/srcs/echoclntsrc.html
 *
 */

/* Just included everything possible .. dont think it makes a
difference to the code */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <syslog.h>
#include <netdb.h>
#include <string.h>
#include <ctype.h>
#include <pwd.h>
#include <regex.h>
#include <sys/time.h>
#include  <signal.h>
#include <unistd.h>
#include <arpa/inet.h>
#define BOUNCEHOST "127.0.0.1"
#define BOUNCEPORT   1601
#define MAX_LINE 1000



/*  Write a line to a socket  */
ssize_t Writeline(int sockd, const void *vptr, size_t n) {
  size_t      nleft;
  ssize_t     nwritten;
  const char *buffer;

  buffer = vptr;
  nleft  = n;


 while ( nleft > 0 ) {
    if ( (nwritten = write(sockd, buffer, nleft)) <= 0 ) {
      if ( errno == EINTR )
        nwritten = 0;
      else
        return -1;
    }
    nleft  -= nwritten;
    buffer += nwritten;
  }

  return n;
}







int main(int argc, char* argv[]) {
  int       conn_s;
  struct    sockaddr_in servaddr;
  char      buffer[MAX_LINE];

  if (argc != 3) {
    fprintf(stderr, "Incorrect usage\n");
    exit(1);
  }
  if ( (conn_s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
    fprintf(stderr, "ECHOCLNT: Error creating listening socket.\n");
    exit(EXIT_FAILURE);
  }
  memset(&servaddr, 0, sizeof(servaddr));
  servaddr.sin_family      = AF_INET;
  servaddr.sin_port        = htons(BOUNCEPORT);
  if ( inet_aton(BOUNCEHOST, &servaddr.sin_addr) <= 0 ) {
    printf("ECHOCLNT: Invalid remote IP address.\n");
    exit(EXIT_FAILURE);
  }
  if ( connect(conn_s, (struct sockaddr *) &servaddr,
sizeof(servaddr) ) < 0 ) {
    printf("ECHOCLNT: Error calling connect()\n");
    exit(EXIT_FAILURE);
  }
  while(fgets(buffer,MAX_LINE,stdin)) Writeline(conn_s, buffer,
strlen(buffer));

  exit(0);

}

[toc] | [prev] | [next] | [standalone]


#10083

FromRalph Spitzner <rasp@spitzner.org>
Date2011-09-10 08:40 +0200
Message-ID<4cdrj8-osh.ln1@spitzner.org>
In reply to#10082
Ram Prasad wrote:
>   while ( nleft>  0 ) {
>      if ( (nwritten = write(sockd, buffer, nleft))<= 0 ) {
>        if ( errno == EINTR )

Use send, or sendto here and set your signals, you might
wait(tm) forever otherwise :-P

	-rasp

[toc] | [prev] | [next] | [standalone]


#10177

FromSeebs <usenet-nospam@seebs.net>
Date2011-09-13 06:44 +0000
Message-ID<slrnj6trlj.2bf0.usenet-nospam@guild.seebs.net>
In reply to#10082
On 2011-09-10, Ram Prasad <ramprasad.ap@gmail.com> wrote:
> Because if I use a perl program  there will be a perl script forked
> everytime when called.
> Much worse than executing a c binary client program.

This is premature optimization.  Have you TESTED the performance?

> This is a part of a mailing system , which receives upto 100k mails an
> hour

*snort*

You seem to be under the mistaken impression that this is a lot.  On a
slowish desktop computer, I can run a perl script 1k times in about 4
seconds, meaning that 100k runs might take just over six minutes.

You're talking about something on the close order of one *tenth* of the
available time -- assuming your server is as slow as my desktop.

> Currently mail reaches postfix , postfix calls a perl script and does
> the processing , looking for particular strings using regex and
> But the things are not quick enough.

Okay, so you have some measurements, but...

> This is not my original idea :-).  Like spamc is used as a small tcp
> client to talk to spamd for antispam spamassassin scanning.

That's because spamd is a HUGE program.

In any event, I am not at all sure that switching perl out for C helps
you very much.  On my system, it was about twice as fast... But I don't
think that's enough to matter, and it might well not stay that way for
a larger thing.  You'd probably be much better off trying to eliminate the
external call *entirely*.

-s
-- 
Copyright 2011, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

[toc] | [prev] | [next] | [standalone]


#10085

FromNobody <nobody@nowhere.com>
Date2011-09-10 08:25 +0100
Message-ID<pan.2011.09.10.07.25.27.642000@nowhere.com>
In reply to#10057
On Fri, 09 Sep 2011 10:46:12 -0700, Ram Prasad wrote:

> I am a perl programmer , need to write a small tcp client in C to pass
> the input to a perl Daemon
> This is going to be a very high volume application , So I better make
> sure the code is efficient enough.

If you want efficiency, see if you can avoid TCP in favour of Unix-domain
sockets. A connection to a  Unix-domain socket is just a bidirectional
pipe. A TCP connection, even one via the loopback interface, involves
splitting the data into packets, calculate checksum, routing, firewall,
validate checksum, reassembly.

As for your code: I don't see any reason to copy the data line-by-line;
replacing fgets() with read() may provide some performance gain.

A bigger performance gain could be obtained by eliminating your program
entirely, by having whatever would otherwise write to your program's stdin
talk to the daemon directly.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web