Use GTK and socket to implement simple chat rooms

Source: Internet
Author: User
Tags socket error
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;
}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.