gmain loop and listening on a port

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

gmain loop and listening on a port

Tim Fulcher - Clickatell
Message
Hi all
 
Please forgive as I'm a newbie with linux and gcc.
 
I'm trying to listen on a socket and am restricted to using g_main_loop, I have set up the socket and have attached the socket to the gmainloop as using g_io_add_watch and then using "accept()" but the port will only listen once.
 
So I tried using select() to read the port and polled that port using g_idle_add and that had the same result.
 
I've attached my code (showing both attempts, one commented out), Surely somebody must have done this before?
 
Kind Regards

Tim Fulcher
 
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <glib-object.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include "time.h"
 
#define   LISTENPORT 7500
#define   BACKLOG 10
 
GIOChannel *listen_sock  = NULL;
int     sock, conn;
struct   sockaddr_in my_addr, client_addr;
int     sockopt_on = 1;
int     sa_in_size = sizeof(struct sockaddr_in);
 
/*int sock, length;
struct sockaddr_in server;
int msgsock;
char buf[1024];
int rval;
fd_set ready;
struct timeval to;*/
 
void Set_Up_Listener()
{
 int opts;
 
 printf("Setting up listener\n");
 
 //get a socket
  if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
    perror("socket");
    exit(1);
  }
 
  //make it reusable
  if (setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&sockopt_on,sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }
 
  opts = fcntl(sock, F_GETFL);
  if (opts < 0) {
   perror("fcntl(sock, F_GETFL)");
   exit(1);
  }
  opts = (opts | O_NONBLOCK);
 if (fcntl(sock,F_SETFL,opts) < 0) {
  perror("fcntl(F_SETFL)");
  exit(1);
 }
 
  //first zero the struct
  memset((char *) &my_addr, 0, sa_in_size);
 
  //now fill in the fields we need
  my_addr.sin_family = PF_INET;
  my_addr.sin_port = htons(LISTENPORT);
  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
 
  //bind our socket to the port
  if (bind(sock,(struct sockaddr *)&my_addr, sa_in_size) == -1) {
    perror("bind");
    exit(1);
  }
 
  //start listening for incoming connections
  if (listen(sock,BACKLOG) == -1) {
    perror("listen");
    exit(1);
  }
 
   /*sock = socket(AF_INET, SOCK_STREAM, 0);
   if (sock < 0) {
      perror("opening stream socket");
      exit(1);
   }
  
   server.sin_family = PF_INET;
   server.sin_addr.s_addr = INADDR_ANY;
   server.sin_port = htons(LISTENPORT);
  
   if (bind(sock, &server, sizeof(server))) {
      perror("binding stream socket");
      exit(1);
   }
   
   length = sizeof(server);
   if (getsockname(sock, &server, &length)) {
      perror("getting socket name");
      exit(1);
   }
   printf("Socket has port #%d\n", ntohs(server.sin_port));
 
   listen(sock, 5);*/
}
 
static void read_sock(gpointer data)
{
 char *servername;
 fd_set ready;
 struct timeval to;
 int readsocks, msgsock;
 char  response[80];
 
 //while(1)
 //{
  conn = accept(sock, (struct sockaddr *)&client_addr, &sa_in_size);
    
  if (conn == -1) {
    perror("accept");
     exit(1);
   }
 
   //log the connecter
   servername = (char*)inet_ntoa(client_addr.sin_addr);
 
   //get the reply
   if (recv(conn, &response, 80, 0) == -1) {
     perror("recv");
   }
 
   printf("The client [%s] says \"%s\"\n",servername, &response);
 
   close(conn);
 //};
 
 /*FD_ZERO(&ready);
  FD_SET(sock, &ready);
  to.tv_sec = 5;
  to.tv_usec = 0;
  if (select(sock + 1, &ready, 0, 0, &to) < 0) {
   perror("select");
  }
 
 if (FD_ISSET(sock, &ready)) {
   msgsock = accept(sock, (struct sockaddr *)0, (int *)0);
    if (msgsock == -1)
     perror("accept");
    else
     do {
       bzero(buf, sizeof(buf));
        if ((rval = read(msgsock, buf, 1024)) < 0)
         perror("reading stream message");
        else
         if (rval == 0)
           printf("Ending connection\n");
          else
           printf("-->%s\n", buf);
      } while (rval > 0);
      close(msgsock);
  } else
   printf("going\n");*/
}
 
static void callback(gpointer data)
{
 struct tm *local;
 time_t t;
 
 t = time(NULL);
  local = localtime(&t);
 
 printf("Timestamped @ %.2d:%.2d:%.2d\n", local->tm_hour, local->tm_min, local->tm_sec);
}
 
int main(int argc, char *argv[]) {
  GMainLoop     *gmain;   /* the receive packet event loop */
     
  //g_thread_init(NULL);
  gmain = g_main_loop_new(NULL, FALSE);
 
  Set_Up_Listener();
 
  listen_sock = g_io_channel_unix_new(sock);
  g_io_add_watch(listen_sock, G_IO_IN, read_sock, NULL);
  //g_timeout_add(1000, (GSourceFunc)callback, NULL);
  //g_idle_add((GSourceFunc)read_sock, NULL);
 
  g_main_loop_run(gmain);
 
  return 0;
}
 
 

_______________________________________________
gtk-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-list
Reply | Threaded
Open this post in threaded view
|

Re: gmain loop and listening on a port

Tim-Philipp Müller
On Friday 05 August 2005 10:44, Tim Fulcher - Clickatell wrote:

> I'm trying to listen on a socket and am restricted to using g_main_loop,
> I have set up the socket and have attached the socket to the gmainloop
> as using g_io_add_watch and then using "accept()" but the port will only
> listen once.
>
> So I tried using select() to read the port and polled that port using
> g_idle_add and that had the same result.
>
> I've attached my code (showing both attempts, one commented out), Surely
> somebody must have done this before?

Have you considered using one of the GLib-based networking libraries out
there, like:

 *  GNet (http://www.gnetlibrary.org), esp. GServer/GConn API
 *  GNetwork

They take care of all the low-level stuff and the main loop integration for
you, and all you need to do is set your callbacks and that's it. Also, your
code will probably be much more portable that way.

Cheers
 -Tim
_______________________________________________
gtk-list mailing list
[hidden email]
http://mail.gnome.org/mailman/listinfo/gtk-list