You're here: Snippet Directory » C/C++ (495)
Language:

Skeleton TCP routines using Glib.

Language: English
Programming Language: C
Published by: centove [not registered]
Last Update: 5/15/2006
Views: 738


Description

This is a basic skeleton of functions that utilize the GIOChannel stuff from glib for a basic tcp server. This will open a socket and do all the work needed for accepting connections and setting up appropriate callbacks. Hook into it at the tcp client_activity section.Call tcp_socket_init (port #) to get everything set up.

Code

1 /* 2 * $Id: $ 3 * 4 * TCP Service -- Handles all socket level issues. 5 */ 6 #ifdef HAVE_CONFIG_H 7 #include <config.h> 8 #endif 9 10 #include <glib.h> 11 #include <errno.h> 12 #include <sys/socket.h> 13 #include <netinet/in.h> 14 #include <arpa/inet.h> 15 #include <fcntl.h> 16 17 /**************************************************************************** 18 * Forward references 19 ***************************************************************************/ 20 gboolean tcp_new_connection (GIOChannel *source, 21 GIOCondition condition, 22 gpointer data); 23 gboolean tcp_client_activity (GIOChannel *source, 24 GIOCondition condition, 25 gpointer data); 26 /**************************************************************************** 27 * Implementation. 28 ***************************************************************************/ 29 void 30 tcp_enable_reuseaddr (gint sock) 31 { 32 gint tmp = 1; 33 if (sock < 0) 34 return; 35 if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (gchar *)&tmp, 36 sizeof (tmp)) == -1) 37 perror ("Bah! Bad setsockopt ()\n"); 38 } 39 40 void 41 tcp_enable_nbio (gint fd) 42 { 43 if (fcntl (fd, F_SETOWN, getpid()) == -1) 44 perror ("fcntl (F_SETOWN) error\n"); 45 if (fcntl (fd, F_SETFL, FNDELAY) == -1) 46 perror ("fcntl (F_SETFL, FNDELAY\n"); 47 } 48 49 void 50 tcp_socket_init (gint port) 51 { 52 gint s; 53 struct sockaddr_in addr; 54 GIOChannel *channel; 55 56 if (port <= 0) 57 return ; 58 59 s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); 60 if (s == -1) 61 return; 62 tcp_enable_reuseaddr (s); 63 memset (&addr, 0, sizeof (addr)); 64 addr.sin_family = AF_INET; 65 addr.sin_port = htons ((u_short)port); 66 addr.sin_addr.s_addr = INADDR_ANY; 67 if (bind (s, (struct sockaddr *)&addr, sizeof (addr)) == -1) 68 { 69 close (s); 70 return ; 71 } 72 if (listen (s, 5) == -1) 73 { 74 close (s); 75 return ; 76 } 77 channel = g_io_channel_unix_new (s); 78 g_io_add_watch (channel, G_IO_IN, tcp_new_connection, NULL); 79 } 80 81 /**************************************************************************** 82 * Callback functions 83 ***************************************************************************/ 84 /** 85 * tcp_new_connection 86 * Will accept a new connection and add the client to the list of clients. 87 * actual client communication is handled elsewhere. 88 **/ 89 gboolean 90 tcp_new_connection (GIOChannel *source, GIOCondition cond, gpointer data) 91 { 92 gint new; /* new socket descriptor */ 93 gint client; 94 GIOChannel *new_channel; 95 struct sockaddr_in client_addr; 96 97 if (cond == G_IO_IN) 98 { 99 if ( (new = accept (g_io_channel_unix_get_fd (source), 100 (struct sockaddr *)&client_addr, &client)) < 0) 101 { 102 g_warning ("Unable to accept new connection."); 103 return FALSE; 104 } 105 new_channel = g_io_channel_unix_new (new); 106 g_io_add_watch (new_channel, G_IO_IN | G_IO_HUP, tcp_client_activity, 107 NULL); 108 } 109 return TRUE; 110 } 111 112 /** 113 * tcp_client_activity 114 * Handles input from the clients and passes it off to the parser/dispatcher. 115 * This will get the raw data from the socket, make sure there is a NULL 116 * terminator, and call the command dispatcher. 117 * If the client has disconnected (condition G_IO_HUP), close the channel and remove 118 * this callback by returning FALSE. 119 **/ 120 gboolean 121 tcp_client_activity (GIOChannel *source, GIOCondition cond, gpointer data) 122 { 123 gchar buf[1024]; 124 guint num_read = 0; 125 126 if (cond == G_IO_IN) 127 { 128 g_print ("Read channel...\n"); 129 if (g_io_channel_read (source, buf, sizeof (buf), &num_read) == G_IO_ERROR_NONE) 130 { 131 buf[num_read] = '\0'; /* Make sure its null terminated */ 132 133 g_print ("Read (%d)\"%s\" from the socket\n", num_read, buf); 134 } 135 } 136 else if (cond == G_IO_HUP) 137 { 138 g_print ("Connection lost.\n"); 139 g_io_channel_close(source); 140 return FALSE; 141 } 142 143 return TRUE; 144 } 145

No comments avaiable

Add a comment

Name *  

Email (won't be displayed) *    

Website  

Comment *  

Sicherheitscode Security Code *    

RSS