Thread: Socket Question

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    68

    Socket Question

    Hello all.

    Firstly, I wasn't sure if this should go in the Networking forum or in the C++ forum, so I posted it here as I figured the C++ people are more likely to look here than the networking one. We'll seoon see

    I've been toying with C for a while, just brought C++ for Dummies figuring I'd consider moving over. Anyway, looking at some socket stuff (not covered by the book, annoyingly) and have followed Beej's network tutorial. However, I'm wondering how I can recieve more that one line of input from a server. I'm assuming I need a while() look in here somewhere, chekcing for multiple lines. Not entirely sure where, and seeing as the tutorial didn't cover it I figured I'd ask

    main.cpp
    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <netdb.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    
    #include "Config.cpp"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
    	/* Setup the configration options. */
    	Configuration.Server = "irc.blitzed.org";
    	Configuration.Channel = "#testing12345";
    	Configuration.RealName = "Test, from DaveHope";
    	Configuration.Port = 6667;
    	Configuration.DataSize = 100;
    	Configuration.Debug = 1;
    
    	int sockfd, numbytes;  
    	char buf[Configuration.DataSize];
    	struct hostent *he;
    	struct sockaddr_in their_addr; // connector's address information 
    
    	if ((he=gethostbyname(Configuration.Server)) == NULL) {
    		perror("gethostbyname");
    		exit(1);
    	}
    
    	if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    		perror("socket");
    		exit(1);
    	}
    
    	their_addr.sin_family = AF_INET;    // host byte order 
    	their_addr.sin_port = htons(Configuration.Port);  // short, network byte order 
    	their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    	memset(&(their_addr.sin_zero), '\0', 8);  // zero the rest of the struct 
    
    	if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
    		perror("connect");
    		exit(1);
    	}
    
    	if ((numbytes=recv(sockfd, buf, Configuration.DataSize-1, 0)) == -1) {
    		perror("recv");
    		exit(1);
    	}
    
    	buf[numbytes] = '\0';
    
    	printf("%s\n",buf);
    
    	/* Close the connection. */
    	close(sockfd);
    
    	/* Exit. */
    	return 0;
    }
    Config.cpp
    Code:
    /*
     *  Configuration Array.
     *  The below struct will hold all configuration information.
     */
    
    struct Configuration
    {
    	/* General Configuration. */
    	int Port;
    	char *Server;
    	char *Channel;
    	char *Nickname;
    	char *RealName;
    	int DataSize;
       
    	/* Debug Mode ? */
    	int Debug;
    	
    	/* Socket/Connection Configuration. */
    	int state;	
    };
    
    struct Configuration Configuration;
    As always, you guys are stars. Thanks for putting up with my so far!

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Networking would be the correct place. Moved.

  3. #3
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Quote Originally Posted by sean_mackrory
    Networking would be the correct place. Moved.
    Typical. 50/50 chance and i guess the wrong one. Ahh well

  4. #4
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Anyway, to answer your question, you can call recv() multiple times - it works just like any other input function - so a loop testing for when input stops would work.

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    So, something like the following perhaps ?

    Code:
    int tmp;
    while (true) {
    tmp = recv(sockfd, buf, Configuration.DataSize-1, 0);
    if (tmp == -1) {
    		perror("recv");
    		exit(1);
    	}
    
    	buf[numbytes] = '\0';
    
    	printf("%s\n",buf);
    }

  6. #6
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    Looks decent - but it's been a really long time since I used sockets outside of C#, so I would wait until someone more experienced confirms that before using it.

  7. #7
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Well, just tried it and it segfaults (compiles without any wanrnings though), so I'll sit and wait

  8. #8
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Just had some help from a friend, I was indeed missing a loop - I just implimented it wrong in my attempt. In case anyone has a similar problem, here's the changed code.

    Code:
    	do {
    		if ((numbytes=recv(sockfd, buf, Configuration.DataSize-1, 0)) == -1) {
    			perror("recv");
    			exit(1);
    		}
    
    		buf[numbytes] = '\0';
    
    		printf("%s\n",buf);
    	} while(numbytes);

  9. #9
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    You could get multiple lines of text with only one call to recv().
    http://faq.cprogramming.com/cgi-bin/...&id=1044780608
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  10. #10
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Alright, I'm now having problems sending data back. At current, I have the following in my do{} loop.
    Code:
    		if (!Configuration.State) {
    			tmp = "USER: test localhost localhost :test\n\r";
    			send(sockfd, tmp, strlen(tmp), 0);
    			tmp = "NICK: test\n\r";
    			send(sockfd, tmp, strlen(tmp), 0);
    			Configuration.State = 1;
    		}
    For some reason, it never seems to send it (but doesn't give an error). Checked, and it does get inside the if statement, just doesn't send the data or error. Suggestions anyone ?

  11. #11
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Sorted. Was a simple misreading of the RFC for that one. - the ':' arn't supposed to be there, that'll teach me not to clean the marks off my monitor.

  12. #12
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    You'd also do well by checking the return code from the send() function to ensure it's worked as requested.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  13. #13
    Registered User
    Join Date
    Dec 2003
    Posts
    68
    Yea, in the real code I am doing. It's now OO too. I just like to get things working in their absolute basics before taking that section of code further

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Socket Question
    By BENCHMARKMAN in forum C Programming
    Replies: 15
    Last Post: 03-12-2008, 09:57 PM
  2. Socket program
    By mhetfield in forum C Programming
    Replies: 5
    Last Post: 04-03-2007, 03:46 PM
  3. Slight problem with socket reading!!!
    By bobthebullet990 in forum C Programming
    Replies: 5
    Last Post: 02-15-2006, 09:55 AM
  4. problem closing socket
    By Wisefool in forum Networking/Device Communication
    Replies: 2
    Last Post: 10-29-2003, 12:19 PM
  5. Simple Socket Question
    By SourceCode in forum Linux Programming
    Replies: 2
    Last Post: 06-22-2003, 09:20 PM