Use GTK and socket to implement simple chat rooms
Last Update:2017-10-15
Source: Internet
Author: User
Use GTK and socket to implement a simple chat room-general Linux technology-Linux technology and application information. The following is a detailed description. (5ty (
When you use GTK and socket to implement a simple chat room, a "segment error" occurs ". Where is the problem ??
Please check out my program. I will use the GTK graphic interface as a simple chat room to implement communication on two machines. Now the program can be compiled, but when running, when the customer segment pop-up logon interface, enter the user name and click OK, the "segment error" will be displayed on the terminal ". I am a newbie. I am just getting started. I hope to reply to my predecessors.
Server:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define OUTPORT 3333
# Define MAX_USERS 8
Struct _ client {
Gint sd;
Gboolean in_use;
Gchar name [64];
Gchar buf [1024];
};
Typedef struct _ client;
Client user [MAX_USERS];
Void do_service (gpointer id)
{
Gint j;
Char tobuf [1024];
While (read (user [GPOINTER_TO_INT (id)]. sd,
User [GPOINTER_TO_INT (id)]. buf, 1024 )! =-1)
{
Sprintf (tobuf, "% s: % s \ n", user [GPOINTER_TO_INT (id)]. name,
User [GPOINTER_TO_INT (id)]. buf );
For (j = 0; j {
If (user [j]. in_use)
{
Write (user [j]. sd, tobuf, 1024 );
G_printf ("% s", tobuf );
}
}
}
User [GPOINTER_TO_INT (id)]. in_use = FALSE;
Close (user [GPOINTER_TO_INT (id)]. sd );
// Exit (0 );
}
Int main (int agrv, char * argv [])
{
Gint sd, newsd;
Struct sockaddr_in * my_addr;/* local address information */
Struct sockaddr_in * remote_addr;/* client address information */
Gint slen;
Gint count = 0;
Gint flags;
Gchar buf [1024];
Gchar tobuf [1024];
Gint length, I, j;
If (! G_thread_supported ())
G_thread_init (NULL );
Else
G_print ("thread not support \ n ");
Sd = socket (AF_INET, SOCK_STREAM, 0 );
If (sd =-1)
{
G_print ("Creat socket error! \ N ");
Return-1;
}
My_addr = g_new (struct sockaddr_in, 1 );
My_addr-> sin_family = AF_INET;
My_addr-> sin_port = htons (OUTPORT );
My_addr-> sin_addr.s_addr = INADDR_ANY;
Bzero (& (my_addr-> sin_zero), 8 );
Slen = sizeof (struct sockaddr_in );
If (bind (sd, (struct sockaddr *) my_addr, slen) <0)
{
G_print ("bind error \ n! ");
Return-1;
}
If (listen (sd, 8) <0)
{
G_print ("listen error! \ N ");
}
For (I = 0; I User. in_use = FALSE;
Flags = fcntl (sd, F_GETFL );
Fcntl (sd, F_GETFL, flags &~ O_NDELAY );
For (;;)
{
Newsd = accept (sd, (struct sockaddr *) remote_addr, & slen );
If (newsd =-1)
{
G_print ("accept error \ n ");
Break;
}
Else
{
If (count> = MAX_USERS)
{
Sprintf (buf, "too many users, the server cannot be connected! \ N ");
Write (newsd, buf, 1024 );
Close (newsd );
}
Else
{
Flags = fcntl (user. sd, F_GETFL );
Fcntl (user. sd, F_SETFL, O_NONBLOCK );
User [count]. sd = newsd;
User [count]. in_use = TRUE;
Read (newsd, user [count]. name, 64 );
G_thread_create (GThreadFunc) do_service,
(Gpointer) count, TRUE, NULL );
Count ++;
}
}
} // (;;)
Close (sd );
G_free (my_addr );
}
Server:
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Define OUTPORT 3333
Gint sd;
Struct sockaddr_in s_in;
Struct hostent * host;
Gchar username [64];
Gchar buf [1024]; // read
Gchar get_buf [1048]; // write
Gboolean isconnected = FALSE;
Static GtkWidget * text;
Static GtkTextBuffer * buffer;
Static GtkWidget * message_entry;
Static GtkWidget * name_entry;
Static GtkWidget * login_button;
Void get_message (void)
{
GtkTextIter iter;
Gchar get_buf [1024];
Gchar buf [1024];
While (read (sd, buf, 1024 )! =-1)
{
Sprintf (get_buf, "% s", buf );
Gdk_threads_enter ();
Gtk_text_buffer_get_end_iter (buffer, & iter );
Gtk_text_buffer_insert (buffer, & iter, get_buf,-1 );
Gdk_threads_leave ();
}
}
Void on_destroy (GtkWidget * widget, GdkEvent * event, gpointer data)
{
Sprintf (username, "guest ");
If (do_connect () = TRUE)
{
Gtk_widget_set_sensitive (login_button, FALSE );
G_thread_create (GThreadFunc) get_message, NULL, FALSE, NULL );
}
Gtk_widget_destroy (widget );
}
Void on_button_clicked (GtkButton * button, gpointer data)
{
Const gchar * name;
Name = gtk_entry_get_text (GTK_ENTRY (name_entry ));
Sprintf (username, "% s", name );
If (do_connect ())
{
Gtk_widget_set_sensitive (login_button, FALSE );
G_thread_create (GThreadFunc) get_message, NULL, FALSE, NULL );
}
Gtk_widget_destroy (data );
}
Void creat_win (void)
{
GtkWidget * win, * vbox;
GtkWidget * button;
Win = gtk_window_new (GTK_WINDOW_TOPLEVEL );
Gtk_window_set_title (GTK_WINDOW (win), "enter user name ");
Gtk_container_set_border_width (GTK_CONTAINER (win), 10 );
G_signal_connect (G_OBJECT (win), "delete_event ",
G_CALLBACK (on_destroy), NULL );
Gtk_window_set_modal (GTK_WINDOW (win), TRUE );
Gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER );
Vbox = gtk_vbox_new (FALSE, 0 );
Gtk_container_add (GTK_CONTAINER (win), vbox );
Name_entry = gtk_entry_new ();
Gtk_box_pack_start (GTK_BOX (vbox), name_entry, TRUE, TRUE, 5 );
Button = gtk_button_new_from_stock (GTK_STOCK_ OK );
G_signal_connect (G_OBJECT (button), "clicked ",
G_CALLBACK (on_button_clicked), win );
Gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 5 );
Gtk_widget_show_all (win );
}
Gboolean do_connect (void)
{
GtkTextIter iter;
Gint slen;
Sd = socket (AF_INET, SOCK_STREAM, 0 );
If (sd <0)
{
Gtk_text_buffer_get_end_iter (buffer, & iter );
Gtk_text_buffer_insert (buffer, & iter, "An error occurred while opening the socket! \ N ",-1 );
Return FALSE;
}
S_in.sin_family = AF_INET;
S_in.sin_port = htons (OUTPORT );
S_in.sin_addr = * (struct in_addr *) host-> h_addr );
Bzero (& (s_in.sin_zero), 8 );
Slen = sizeof (s_in );
If (connect (sd, (struct sockaddr *) & s_in, slen) <0)
{
Gtk_text_buffer_get_end_iter (buffer, & iter );
Gtk_text_buffer_insert (buffer, & iter, "An error occurred while connecting to the server! \ N ",-1 );
Return FALSE;
}
Else
{
Gtk_text_buffer_get_end_iter (buffer, & iter );
Gtk_text_buffer_insert (buffer, & iter, username,-1 );
Gtk_text_buffer_get_end_iter (buffer, & iter );
Gtk_text_buffer_insert (buffer, & iter, "\ n successfully connected to the server! \ N ",-1 );
//
Write (sd, username, 64 );
//
Isconnected = TRUE;
Return TRUE;
}
}
Void on_send (GtkButton * button, gpointer data)
{
Const char * message;
If (isconnected = FALSE) return;
Message = gtk_entry_get_text (GTK_ENTRY (message_entry ));
Sprintf (buf, "% s \ n", message );
Write (sd, buf, 1024 );
Gtk_entry_set_text (GTK_ENTRY (message_entry ),"");
}
Void on_login (GtkWidget * widget, GdkEvent * weent, gpointer data)
{
Creat_win ();
}
Void on_delete_event (GtkWidget * widget, GdkEvent * event, gpointer data)
{
Close (sd );
Gtk_main_quit ();
}
Int main (int argc, char * argv [])
{
GtkWidget * window;
GtkWidget * vbox, * hbox, * button, * label, * view;
If (! G_thread_supported ())
G_thread_init (NULL );
Gtk_init (& argc, & argv );
Window = gtk_window_new (GTK_WINDOW_TOPLEVEL );
Gtk_window_set_title (GTK_WINDOW (window), "client ");
G_signal_connect (G_OBJECT (window), "delete_event ",
G_CALLBACK (on_delete_event), NULL );
Gtk_container_set_border_width (GTK_CONTAINER (window), 10 );
Vbox = gtk_vbox_new (FALSE, 0 );
Gtk_container_add (GTK_CONTAINER (window), vbox );
Hbox = gtk_hbox_new (FALSE, 0 );
Gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5 );
Label = gtk_label_new ("click" Log on "to connect to the server ");
Gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5 );
Login_button = gtk_button_new_with_label ("login ");
Gtk_box_pack_start (GTK_BOX (hbox), login_button, FALSE, FALSE, 5 );
G_signal_connect (G_OBJECT (login_button), "clicked ",
G_CALLBACK (on_login), NULL );
View = gtk_scrolled_window_new (NULL, NULL );
Gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view ),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
Text = gtk_text_view_new ();
Gtk_box_pack_start (GTK_BOX (vbox), view, TRUE, TRUE, 5 );
Gtk_container_add (GTK_CONTAINER (view), text );
Buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text ));
Hbox = gtk_hbox_new (FALSE, 0 );
Gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5 );
Label = gtk_label_new ("input :");
Gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5 );
Message_entry = gtk_entry_new ();
Gtk_box_pack_start (GTK_BOX (hbox), message_entry, FALSE, FALSE, 5 );
Button = gtk_button_new_with_label ("send ");
Gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 5 );
G_signal_connect (G_OBJECT (button), "clicked ",
G_CALLBACK (on_send), NULL );
Gtk_widget_show_all (window );
Gdk_threads_enter ();
Gtk_main ();
Gdk_threads_leave ();
Return FALSE;
}