LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 12-24-2009, 01:01 AM   #1
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Rep: Reputation: 32
Question socket IPC..


I am trying to get some IPC working within a program. Basically I need iostream to print text every so many seconds, and at the same time be able to accept input from the keyboard (which would execute a function).

Currently I have a select() function which executes some code when it times out. It is set within a loop, so it executes every few seconds, which works well.
I (thought I had) set it up to execute a different piece of code if iostream input is received, but this part never gets executed.

I am vaguely familiar with IPC methods, would a different IPC method be more(or evenly) practical for this situation? A pipe maybe?, or message queues?

Do I need to use fork() to have one process that controls the timeout function, and another which checks for input?

Some pseudocode and keywords would be appreciated.
 
Old 12-25-2009, 12:00 PM   #2
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Please reduce your code as much as possible (while still reproducing the problem) and post it.
Kevin Barry
 
Old 12-25-2009, 12:26 PM   #3
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by vendtagain View Post
I am trying to get some IPC working within a program. Basically I need iostream to print text every so many seconds, and at the same time be able to accept input from the keyboard (which would execute a function).

Currently I have a select() function which executes some code when it times out. It is set within a loop, so it executes every few seconds, which works well.
I (thought I had) set it up to execute a different piece of code if iostream input is received, but this part never gets executed.

I am vaguely familiar with IPC methods, would a different IPC method be more(or evenly) practical for this situation? A pipe maybe?, or message queues?

Do I need to use fork() to have one process that controls the timeout function, and another which checks for input?

Some pseudocode and keywords would be appreciated.
IIRC there are socket related functions which tell how much data is in the socket and do not block. So, one doesn't even need a separate thread/fork, i.e. one can more or less implement the following concept:

Code:
unsigned desired_number_of_items = ...; // put real value here
some_type time_to_sleep_between_check = ...; // put real value here
for(;;)
  {
  if(number_of_items_in_socket(socket) < desired_number_of_items)
    {
    sleep(time_to_sleep_between_checks);
    }
  else
    {
    read_data_from_socket(socket);
    break;
    }
  }
You may easily add timeout to the above pseudocode.
 
Old 12-25-2009, 02:41 PM   #4
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
vendtagain -

Quote:
Currently I have a select() function which executes some code when it times out. It is set within a loop, so it executes every few seconds
You're polling.

Polling is Bad.

You're already using "select()". "Select()" does multiplexing.

Multiplexing is Good.

Give it a try.

IMHO .. PSM
 
Old 12-25-2009, 07:06 PM   #5
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
Code:
   fd_set fdset;
   struct timeval timeout;
struct timeval timer1,timer2;
   int  rc;
   char  val;

   timeout.tv_sec = 0;   // wait for 1 seconds for data
   timeout.tv_usec = 500000;
   FD_ZERO(&fdset);
   FD_SET(0, &fdset);
bool done = 0;
tmap.cursorMap();

 while(done == 0)
{
gettimeofday(&timer1,NULL);

   rc = select(1, &fdset, NULL, NULL, &timeout);
   if (rc == -1)  // select failed
   {
       std::cout<<"error: select failed with -1\n";
	done = 1;
   }
   else if (rc == 0)  //select timed out
   {
      std::cout<<"timeout\n";
	syncmove();
	tmap.cursorMap();
	timeout.tv_sec = 0;
	timeout.tv_usec = 500000;
   }
   else   //character is entered
   {
      if (FD_ISSET(0, &fdset)) 
      {
        val = getchar();
	std::cout<<"val == "<<val;
           gettimeofday(&timer2,NULL);
           timeout.tv_sec = timeout.tv_sec - (timer2.tv_sec - timer1.tv_sec);
           timeout.tv_usec = timeout.tv_usec - (timer2.tv_usec - timer1.tv_usec);
      }
   }

}
 
Old 12-25-2009, 07:23 PM   #6
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by vendtagain View Post
Code:
   fd_set fdset;
   struct timeval timeout;
struct timeval timer1,timer2;
   int  rc;
   char  val;

   timeout.tv_sec = 0;   // wait for 1 seconds for data
   timeout.tv_usec = 500000;
   FD_ZERO(&fdset);
   FD_SET(0, &fdset);
bool done = 0;
tmap.cursorMap();

 while(done == 0)
{
gettimeofday(&timer1,NULL);

   rc = select(1, &fdset, NULL, NULL, &timeout);
   if (rc == -1)  // select failed
   {
       std::cout<<"error: select failed with -1\n";
	done = 1;
   }
   else if (rc == 0)  //select timed out
   {
      std::cout<<"timeout\n";
	syncmove();
	tmap.cursorMap();
	timeout.tv_sec = 0;
	timeout.tv_usec = 500000;
   }
   else   //character is entered
   {
      if (FD_ISSET(0, &fdset)) 
      {
        val = getchar();
	std::cout<<"val == "<<val;
           gettimeofday(&timer2,NULL);
           timeout.tv_sec = timeout.tv_sec - (timer2.tv_sec - timer1.tv_sec);
           timeout.tv_usec = timeout.tv_usec - (timer2.tv_usec - timer1.tv_usec);
      }
   }

}
Why do you set

timeout.tv_sec
timeout.tv_usec

in three places ?

Where the values of

Code:
timeout.tv_sec = timeout.tv_sec - (timer2.tv_sec - timer1.tv_sec);
           timeout.tv_usec = timeout.tv_usec - (timer2.tv_usec - timer1.tv_usec);
are used ?

If they are meant to be used as the new timeout, why the timeout should change ?


Why is 'rc' defined outside the 'while' body ? Is it needed outside the 'while' body ?
 
Old 12-25-2009, 07:38 PM   #7
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
Quote:
Why do you set

timeout.tv_sec
timeout.tv_usec

in three places ?
If a key is pressed, an action occurs and the loop begins again. I would like to keep the structure in timeout section to occur every .5 secs, so if a key is pressed I dont want the timer to start over at .5, but begin where it left off when the key is pressed. I assumed this would be the best way to do this.
Do you mean the timeout section of the nested if structure would occur every .5 seconds, if a key was pressed or not?

Quote:
Why is 'rc' defined outside the 'while' body ? Is it needed outside the 'while' body ?
I can't give you a good answer here, I'm am still trying to figure this stuff out.

Last edited by vendtagain; 12-25-2009 at 07:42 PM.
 
Old 12-25-2009, 08:04 PM   #8
Sergei Steshenko
Senior Member
 
Registered: May 2005
Posts: 4,481

Rep: Reputation: 454Reputation: 454Reputation: 454Reputation: 454Reputation: 454
Quote:
Originally Posted by vendtagain View Post
If a key is pressed, an action occurs and the loop begins again. I would like to keep the structure in timeout section to occur every .5 secs, so if a key is pressed I dont want the timer to start over at .5, but begin where it left off when the key is pressed. I assumed this would be the best way to do this.
Do you mean the timeout section of the nested if structure would occur every .5 seconds, if a key was pressed or not?


I can't give you a good answer here, I'm am still trying to figure this stuff out.
Suppose you initialized the timeout value to be 0.5 seconds and a key was pressed 0.25 seconds after the initialization.

If I understand you correctly, you want to wait for the next key to be pressed again at most 0.5 seconds. If it's the case, which part of your code will set timeout to become 0.5 seconds again ?

Regarding 'rc' and stuff like that - the rule of thumb is: one creates an object (in human, not necessarily OO) sense as late as possible and disposes of it as early as possible. Believe me, it really helps to keep mess away regardless of programming language.
 
Old 12-26-2009, 01:31 PM   #9
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
Question

I think I need to find some guides and docs relating to sockets, IPC or (multiplexing?). to read through. I haven't been able to find any good ones yet.

Any suggestions?
 
Old 12-26-2009, 05:16 PM   #10
paulsm4
LQ Guru
 
Registered: Mar 2004
Distribution: SusE 8.2
Posts: 5,863
Blog Entries: 1

Rep: Reputation: Disabled
Hi -

Beej's guide is a *superb* resource:

http://beej.us/guide/bgnet/

He also wrote one on IPC:

http://beej.us/guide/bgipc/

The single best book I've ever read on sockets programming (IMHO) is Stevens:

http://www.amazon.com/dp/0131411551/

He also wrote a brilliant book on Unix programming in general (including IPCs):

http://www.amazon.com/dp/0321525949/

'Hope that helps .. PSM
 
Old 12-26-2009, 07:41 PM   #11
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by vendtagain View Post
If a key is pressed, an action occurs and the loop begins again. I would like to keep the structure in timeout section to occur every .5 secs, so if a key is pressed I dont want the timer to start over at .5, but begin where it left off when the key is pressed. I assumed this would be the best way to do this.
Maybe you should use setitimer to have it executed every .5s, then use select with a timeout of 0s when the timer is triggered. To do that you might start a thread blocked with a pthread condition that the timer releases, that way you don't interrupt a read in progress.
Kevin Barry

edit: Take a look at this for timing.
https://developer.berlios.de/snippet...ppet&id=100040

Last edited by ta0kira; 12-27-2009 at 06:29 PM.
 
Old 01-01-2010, 07:23 PM   #12
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
Question

Quote:
Beej's guide is a *superb* resource:

http://beej.us/guide/bgnet/
I agree this is a superb guide.
This is actually the one I've been using, I'm on my 3rd go-around.

I still can't get my head around a client that would be ready to receive info from a server, and also send info if something is inputted.

code below is a server I've developed based on beej's guide which should send info to all clients when it is received from any client.

Now I still can't figure how to implement a client that would wait for info being sent from the server, but would also be able to send info inputted via local cin input.

*main server loop...
Code:
int sockfd, new_fd;
fd_set master,read_fds,write_fds;
int fdmax;
struct sockaddr_storage remoteaddr;
socklen_t addrlen;

sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
fdmax = sockfd;  //max so far
FD_SET(sockfd, &master);

for(;;)
{
write_fds = read_fds = master;

select(fdmax+1, &read_fds, &write_fds, NULL, &time_out);

   for(i = 0; i <= fdmax; i++) {
   {
      if (FD_ISSET(i, &read_fds))
      {

        if (i == sockfd)// handle new connections
	{  addrlen = sizeof remoteaddr;
         newfd = accept(sockfd,(struct sockaddr *)&remoteaddr,&addrlen);
         FD_SET(newfd, &master); //add new connection to master set
          fdmax = newfd;
	}
        else
        {
         //client on socket i is "send()"ing info
          nbytes = recv(i,bufdata,sizeof bufdata,0);
            for(jj=0;jj<=fdmax;jj++)
            {
                if (jj!=sockfd && jj!=i)
                {  //send data to all but listener and sender
                     send(jj,bufdata,nbytes,0);
                }
            }
        }

      }

      if (FD_ISSET(i, &write_fds))
      {

      }

   }
}
I'm not even sure how to look at getting the client set up (to wait for keyboard input and server socket recv()), or what to look into, so thought maybe posting the server would help someone give me some insight.

Last edited by vendtagain; 01-02-2010 at 12:23 AM. Reason: minor fixes
 
Old 01-02-2010, 12:35 AM   #13
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
if (cin >> jj_input)
send(...);
else
recv(...);
?
?Seems like a fairly simple logic...just need cin and recv to be ready for action, simultaneously...without blocking each other

can cin, getline(), or keyboard inputstream be a sort of socket descriptor?

Last edited by vendtagain; 01-02-2010 at 12:45 AM.
 
Old 01-03-2010, 04:15 PM   #14
vendtagain
Member
 
Registered: Sep 2009
Distribution: Slackware, Debian, Mac OS X, Zenwalk, Puppy, Gentoo
Posts: 199

Original Poster
Rep: Reputation: 32
I didnt quite realize how threading worked, but from a few tests with pthreads, it seems I should be able to use them in this case effectively. Thanks for the input.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
/usr/sbin/in.telnetd: getpeername: Socket operation on non-socket vnaveen Linux - Networking 1 05-05-2009 04:42 AM
Can't connect to UNIX socket /var/run/clamav/clamd.socket ganick Linux - Server 8 08-01-2008 01:22 PM
cannot read data at server socket, though client socket sends it jacques83 Linux - Networking 0 11-15-2005 01:58 PM
Unable to connect to UNIX socket /tmp/.esd/socket error while using grip dr_zayus69 Linux - Software 4 08-23-2005 07:28 PM
IPC in socket using select system call Gomathy Linux - Networking 0 01-28-2005 06:37 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:47 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration