From: Eric Sosman on 12 May 2010 15:53 On 5/12/2010 3:30 PM, barncat wrote: > > Thanks John. I was not sure how much code to post. I did not want to > post too much. i am trying to figure this out with your and Eric's > suggestions. i will post all code if I can't get it working. General suggestion, not just for your current problem: Begin by getting rid of the inessentials and distractions, to put the mystery into the foreground. In your code, for example, you could jettison the space-squeezing stuff, and perhaps more. How do you know what's relevant and what isn't? If the reduced program still shows the same mystifying behavior, the relevant pieces are still there. (If it suddenly starts behaving, chances are good -- but not, alas, certain -- that the last thing you threw out had something to do with the problem.) Ideally, you'll distill the program down to an SSCCE: a Short, Self-Contained, Complete Example (some people prefer Correct or Compilable for the second C): <http://sscce.org/>. All of these attributes are important when you're asking for volunteer help, so give the exercise some attention. There's a bonus: It quite often happens that the distillation process itself will reveal the problem to you and enable you to solve it yourself! -- Eric Sosman esosman(a)ieee-dot-org.invalid
From: David Schwartz on 12 May 2010 17:50 On May 12, 10:41 am, barncat <thebarn...(a)gmail.com> wrote: > if (send(socket, string, strlen(string), 0) == -1) > perror("Writing String to client"); What is the protocol you are using over this socket? Do you have a specification for it? Without a specification, if something goes wrong, there is no way to know who to blame. With a specification, use this logic: 1) Check if the program that is having trouble follows the specification. If not, it is broken. 2) Check if the program on the other end follows the specification. If not, it is broken. 3) If you get to this step, the specification is broken. See, your 'send' provides no obvious way for the program on the other end to determine whether or not it got the whole message. To know if this is correct or the cause of your problem, we need to check the specification to see if it was supposed to. And to write the other end correctly, it will need to follow the specification to know how to know whether to process the message or wait for more data. DS
From: barncat on 12 May 2010 19:31 On May 12, 3:53 pm, Eric Sosman <esos...(a)ieee-dot-org.invalid> wrote: > On 5/12/2010 3:30 PM, barncat wrote: > > > General suggestion, not just for your current problem: Begin > by getting rid of the inessentials and distractions, to put the > mystery into the foreground. In your code, for example, you could > jettison the space-squeezing stuff, and perhaps more. How do you > know what's relevant and what isn't? If the reduced program still > shows the same mystifying behavior, the relevant pieces are still > there. (If it suddenly starts behaving, chances are good -- but not, > alas, certain -- that the last thing you threw out had something to > do with the problem.) > > Ideally, you'll distill the program down to an SSCCE: a Short, > Self-Contained, Complete Example (some people prefer Correct or > Compilable for the second C): <http://sscce.org/>. All of these > attributes are important when you're asking for volunteer help, so > give the exercise some attention. There's a bonus: It quite often > happens that the distillation process itself will reveal the problem > to you and enable you to solve it yourself! > i got it to "work" but probably not the correct way. any comments on better ways to do this are appreciated. i hope this is not too much cod but it does compile and returns the expected output: -bash-2.05b$ ./client INFO server Type:Dedicated Mode:Capped -------------------------- server: #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <time.h> #include <signal.h> #include <stdio.h> #include <string.h> #include <strings.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <sys/wait.h> #define PORT 3490 #define BACKLOG 5 #define BUFLEN 1024 int squeeze(char *s) { char *t = s; for(;*s;(*s != ' ') ? *t++ = *s++ : *s++) continue; *t = '\0'; } int sendInfo(int socket) { FILE *FP; char string[128]; char buf[64]; int len; bzero(string,128); FP = popen("lparstat -i | head -5 | tail -2","r"); while(fgets(buf,64,FP) != NULL) { strcat(string,buf); squeeze(string); } pclose(FP); len = strlen(string); string[len] = '\0'; if (send(socket, string, strlen(string) + 1, 0) == -1) perror("Writing String to client"); return(1); } int main(void) { int sockfd, new_fd; int len; int yes=1; pid_t pid; socklen_t sin_size; struct sockaddr_in serv_addr, cli_addr; struct hostent *h; struct sigaction sa; char request[BUFLEN+1]; char* pc; int rc; char c[32]; /* client ip string buffer */ /* set sock addrs info */ memset(&serv_addr, 0, sizeof serv_addr); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(PORT); if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("server:socket"); exit(1); } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } /* bind 32 bit adr and 16 bit port to unamed sock */ if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { perror("server: bind"); exit(1); } /* convert unconnected sock to a passive sock */ if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } /* Accept requests and create file desc for each cli conn */ while(1) { sin_size = sizeof cli_addr; new_fd = accept(sockfd, (struct sockaddr *)&cli_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(AF_INET, &cli_addr.sin_addr, c, sizeof c); printf("got connection from %s\n", c); pid = fork(); if (pid == 0) { // child close(sockfd); // child doesn't need the listener /* Read data from cli socket into request */ pc = request; while (rc = read(new_fd, pc, BUFLEN - (pc- request))) { pc += rc; } *pc = '\0'; if (strcmp(request,"INFO") == 0) sendInfo(new_fd); close(new_fd); exit(0); } /* end fork */ } /* end of while loop */ } /* end of main body */ -- client: #include <stdio.h> /* Basic I/O routines */ #include <stdlib.h> #include <unistd.h> #include <sys/types.h> /* standard system types */ #include <netinet/in.h> /* Internet address structures */ #include <sys/socket.h> /* socket interface functions */ #include <netdb.h> /* host to IP resolution */ #include <errno.h> #include <string.h> #include <arpa/inet.h> #define BUFLEN 1024 /* maximum response size */ #define PORT 3490 int main(int argc, char *argv[]) { int n, i; int length; char request[BUFLEN+1]; char hostname[64]; char ServerInfo[128]; int sockfd; struct hostent *h; struct sockaddr_in sin; /* Address resolution of Server we are connecting to */ h = gethostbyname(argv[2]); if (!h) { perror("couldn't resolve host name"); } strcpy(request,argv[1]); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); memcpy(&sin.sin_addr,h->h_addr,h->h_length); /* open a socket */ if ((sockfd = socket(AF_INET,SOCK_STREAM,0)) < 0) { perror("client:socket"); exit(1); } /* connect to the socket */ if (connect(sockfd, (struct sockaddr*)&sin, sizeof(sin)) < 0) { perror("client: connect"); exit(1); } /* Send request to host server OS,SerialNum,... */ if (n = write(sockfd, request, BUFLEN) < 0) perror("writing request to socket"); /* Read back response from server */ if (read(sockfd, ServerInfo, 128), 0) perror("Reading back server data"); printf("%s\n",ServerInfo); close(sockfd); }
From: Barry Margolin on 12 May 2010 20:42 In article <e9c77949-3250-4167-85d7-fe4bb39e248a(a)o8g2000yqo.googlegroups.com>, barncat <thebarncat(a)gmail.com> wrote: > hi > I am reading data from a popen call (server) and sending the data to a > client. It works fine except funny chars are prepended to the string > sent and displayed at the client. here is the relevant code: I think it's because of strcat(string, buf). You never initialized string[], so it contains garbage, and then you append buf to that. > -- > FILE *FP; > char string[32]; > char buf[128]; > FP = popen("lparstat -i | head -5 | tail -2","r"); > while(fgets(buf,128,FP) != NULL) { > strcat(string,buf); > squeeze(string); //function to remove spaces > } > pclose(FP); > if (send(socket, string, strlen(string), 0) == -1) > perror("Writing String to client"); > -- > /* function to remove spaces */ > int squeeze(char *s) { > char *t = s; > for(;*s;(*s != ' ') ? *t++ = *s++ : *s++) > continue; > *t = '\0'; > } > -- > > Output from client: > > -bash-2.05b$ ./program > received answer to query from server: > /�,�/�,�Type:Dedicated > Mode:Capped > -- > > Thanks, > Jim -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
From: Eric Sosman on 12 May 2010 20:57 On 5/12/2010 7:31 PM, barncat wrote: > > i got it to "work" but probably not the correct way. any comments on > better ways to do this are appreciated. i hope this is not too much > cod but it does compile and returns the expected output: > -bash-2.05b$ ./client INFO server > Type:Dedicated > Mode:Capped > -------------------------- > > server: > #include<sys/types.h> > #include<sys/socket.h> > #include<netinet/in.h> > #include<netdb.h> > #include<time.h> > #include<signal.h> > #include<stdio.h> > #include<string.h> > #include<strings.h> > #include<unistd.h> > #include<fcntl.h> > #include<stdlib.h> > #include<errno.h> > #include<sys/wait.h> You have not expended much effort toward reducing your program to a minimal example. At a cursory look, you seem to be using *nothing* that requires <time.h>, nor <signal.h>, nor <errno.h>, nor <strings.h> (whatever the Hell *that* is), and I'd be there are yet more superfluous relics here, whose only purpose is to give the would-be helper more useless junk to wade through. Okay, fine: I'll set a limit on my wading depth, and I'll count all these extraneous lines against that limit, and at some point I'll reach my tolerance for sludge. > #define PORT 3490 > #define BACKLOG 5 > #define BUFLEN 1024 > > int squeeze(char *s) { > char *t = s; > for(;*s;(*s != ' ') ? *t++ = *s++ : *s++) > continue; This is still obfuscated and ugly -- but beauty is in the eye of the beholder, and besides: it's a side-issue. > *t = '\0'; > } > > int sendInfo(int socket) { > FILE *FP; > char string[128]; > char buf[64]; > int len; > bzero(string,128); Overkill. All you actually need is `string[0] = 0;'. > FP = popen("lparstat -i | head -5 | tail -2","r"); > while(fgets(buf,64,FP) != NULL) { > strcat(string,buf); Still vulnerable to buffer overflow. Each individual chunk will fit, yes, but what if the other end sends you a hundred of them? How do you expect to fit 6301 characters in a 128-char array? > squeeze(string); Wasteful. You squeeze the first chunk, then append a second and squeeze them both (re-squeezing the first uselessly), then append a third and squeeze all three (re-re-squeezing the first and re-squeezing the second), then ... > } > pclose(FP); > > len = strlen(string); > string[len] = '\0'; Utterly pointless, utterly. How do you suppose strlen() determines its result? By locating the '\0', that's right. So, what character is *already* at string[len]? (Now, let's not always see the same hands ...) > if (send(socket, string, strlen(string) + 1, 0) == -1) > perror("Writing String to client"); Interesting that you carefully check for send() errors but don't bother to check for popen() problems ... > return(1); Interesting, too, that you always return 1. Success? Return 1. Failure? Return 1. 1 is 1 and all alone and ever more ... oh, sorry. >[...] Heck with it. Sludge tolerance reached. Going no further until some evidence of cooperation appears, or until you start paying me. -- Eric Sosman esosman(a)ieee-dot-org.invalid
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Difference between service and process?? Next: New functional language - Fling |