歡迎您光臨本站 註冊首頁

Linux下用GTK和socket實現簡單的聊天室

←手機掃碼閱讀     火星人 @ 2014-03-12 , reply:0
   

用GTK和socket實現簡單的聊天室,出現“段錯誤”。是哪裡的問題??

麻煩看看我的程序,我要用GTK圖形界面做一個簡單的聊天室,在兩台機器上實現通信。現在程序可以編譯過去,但是運行時,當客戶段彈出登錄界面時,輸入用戶名再點擊確定的時候,就在終端顯示“段錯誤”。我是新手,剛剛入門,向前輩們請教,盼回復。

 

伺服器端:

 

 

#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;    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; /* 本機地址信息 */    struct sockaddr_in *remote_addr; /* 客戶端地址信息 */  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,"用戶數量過多,伺服器不能連接!\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++;  }  }  }//for(;;)    close(sd);  g_free(my_addr);  }

 

 

 

伺服器端:

 

 

#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),"輸入用戶名");  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,"打開套接字時出錯!\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,"連接伺服器時出錯!\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成功於伺服器連接!\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),"客戶端");  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("點擊登錄按鈕連接伺服器");  gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,5);  login_button=gtk_button_new_with_label("登錄");  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("輸入:");  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("發送");  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;  }

 

(責任編輯:A6)



[火星人 ] Linux下用GTK和socket實現簡單的聊天室已經有899次圍觀

http://coctec.com/docs/program/show-post-71693.html