[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Small tcp client for review

ram

9/9/2011 5:46:00 PM

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.co...


Thanks
Ram

6 Answers

Ben Bacarisse

9/9/2011 7:45:00 PM

0

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.co...

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.

Gene

9/9/2011 8:43:00 PM

0

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.

ram

9/10/2011 6:02:00 AM

0

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/echocl...
*
*/

/* 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);

}

Ralph Spitzner

9/10/2011 6:41:00 AM

0

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

John Doe

9/10/2011 7:25:00 AM

0

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.

Seebs

9/13/2011 6:44:00 AM

0

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.seeb... <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/...(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.