GTK+2.0 编程范例

软件和网站开发以及相关技术探讨
johnnr
帖子: 40
注册时间: 2013-02-19 6:28

Re: GTK+2.0 编程范例

#31

帖子 johnnr » 2013-04-22 19:58

顶一下。想用gtk+实现简单曲线动画。
chenzf070720
帖子: 1
注册时间: 2013-10-08 13:46
系统: ubuntu

Re: GTK+2.0 编程范例

#32

帖子 chenzf070720 » 2013-10-08 14:09

正在搭建环境。先下载了。谢谢!
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙

Re: GTK+2.0 编程范例

#33

帖子 eexpress » 2013-10-08 14:58

chenzf070720 写了:正在搭建环境。先下载了。谢谢!
现在都是gtk3了。你干嘛。
● 鸣学
nae6taiyie0T
帖子: 482
注册时间: 2013-09-13 0:42
系统: Debian sid

Re: GTK+2.0 编程范例

#34

帖子 nae6taiyie0T » 2013-10-08 15:32

eexpress 写了:
chenzf070720 写了:正在搭建环境。先下载了。谢谢!
现在都是gtk3了。你干嘛。
gtk3 都已经到了3.8, 这怎么还在说gtk2呀? 难不成是因为gtk3的中文文档太少了? ~~
lancesaber
帖子: 1
注册时间: 2013-12-24 21:36
系统: win 8

Re: GTK+2.0 编程范例

#35

帖子 lancesaber » 2014-05-02 9:40

我觉得现在看这本书会不会有点过时,毕竟十几年前 的东东了 :em06
头像
mofi
帖子: 35
注册时间: 2012-11-20 15:42
系统: ubuntu/windows7

Re: GTK+2.0 编程范例

#36

帖子 mofi » 2014-05-17 5:48

代码: 全选

#include<glib.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<netdb.h>
#include<netinet/in.h>


#define OURPORT 8088
#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<MAX_USERS;j++)
	{
		if(user[j].in_use)
		{
			write(user[j].sd,tobuf,1024);
			g_print("%s",tobuf);
		}
	}
}
user[GPOINTER_TO_INT(id)].in_use=FALSE;
close(user[GPOINTER_TO_INT(id)].sd);
}

int main(int argc,char *argv[])
{
	gint sd,newsd;
	struct sockaddr_in *sin;
	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 supported\n");
	sd= socket(AF_INET,SOCK_STREAM,0);
	if(sd== -1)
	{
		g_print("create socket error!\n");
		return -1;
	}

	sin= g_new(struct sockaddr_in,1);
	sin->sin_family=AF_INET;
	sin->sin_port=OURPORT;
	slen=sizeof(struct sockaddr_in);
	
	if(bind(sd,sin,slen)< 0)
	{
		g_print("bind erro!\n");
		return -1;
	}

	if(listen(sd,8)<0)
	{
		g_print("listen error!\n");
		return -1;
	}

	for(i=0;i<MAX_USERS;i++)
		user[i].in_use=FALSE;

	flags= fcntl(sd,F_GETFL);
	fcntl(sd,F_SETFL,flags&~O_NDELAY);

	for(;;)
	{
		newsd=accept(sd,sin,&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[i].sd,F_GETFL);
				fcntl(user[i].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(sin);
}

#include<gtk/gtk.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define OURPORT 8088

gint sd;
struct sockaddr_in s_in;
gchar username[64];
gchar buf[1024];
gchar get_buf[1048];
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 create_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=OURPORT;
	slen=sizeof(s_in);
	if(connect(sd,&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 *button,gpointer data)
{
	create_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;
}

那个多人聊天的代码怎么运行不起来啊我,是哪里出问题了,求指教下哈,服务端总是显示thread not support,我用的是ubuntu14,
nae6taiyie0T
帖子: 482
注册时间: 2013-09-13 0:42
系统: Debian sid

Re: GTK+2.0 编程范例

#37

帖子 nae6taiyie0T » 2014-05-17 6:30

mofi 写了:

代码: 全选

#include<glib.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<netdb.h>
#include<netinet/in.h>


#define OURPORT 8088
#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<MAX_USERS;j++)
	{
		if(user[j].in_use)
		{
			write(user[j].sd,tobuf,1024);
			g_print("%s",tobuf);
		}
	}
}
user[GPOINTER_TO_INT(id)].in_use=FALSE;
close(user[GPOINTER_TO_INT(id)].sd);
}

int main(int argc,char *argv[])
{
	gint sd,newsd;
	struct sockaddr_in *sin;
	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 supported\n");
	sd= socket(AF_INET,SOCK_STREAM,0);
	if(sd== -1)
	{
		g_print("create socket error!\n");
		return -1;
	}

	sin= g_new(struct sockaddr_in,1);
	sin->sin_family=AF_INET;
	sin->sin_port=OURPORT;
	slen=sizeof(struct sockaddr_in);
	
	if(bind(sd,sin,slen)< 0)
	{
		g_print("bind erro!\n");
		return -1;
	}

	if(listen(sd,8)<0)
	{
		g_print("listen error!\n");
		return -1;
	}

	for(i=0;i<MAX_USERS;i++)
		user[i].in_use=FALSE;

	flags= fcntl(sd,F_GETFL);
	fcntl(sd,F_SETFL,flags&~O_NDELAY);

	for(;;)
	{
		newsd=accept(sd,sin,&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[i].sd,F_GETFL);
				fcntl(user[i].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(sin);
}

#include<gtk/gtk.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define OURPORT 8088

gint sd;
struct sockaddr_in s_in;
gchar username[64];
gchar buf[1024];
gchar get_buf[1048];
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 create_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=OURPORT;
	slen=sizeof(s_in);
	if(connect(sd,&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 *button,gpointer data)
{
	create_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;
}

那个多人聊天的代码怎么运行不起来啊我,是哪里出问题了,求指教下哈,服务端总是显示thread not support,我用的是ubuntu14,
你在编译时加入了thread头文件吗?
头像
mofi
帖子: 35
注册时间: 2012-11-20 15:42
系统: ubuntu/windows7

Re: GTK+2.0 编程范例

#38

帖子 mofi » 2014-05-17 7:48

nae6taiyie0T 写了:
mofi 写了:

代码: 全选

#include<glib.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<netdb.h>
#include<netinet/in.h>


#define OURPORT 8088
#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<MAX_USERS;j++)
	{
		if(user[j].in_use)
		{
			write(user[j].sd,tobuf,1024);
			g_print("%s",tobuf);
		}
	}
}
user[GPOINTER_TO_INT(id)].in_use=FALSE;
close(user[GPOINTER_TO_INT(id)].sd);
}

int main(int argc,char *argv[])
{
	gint sd,newsd;
	struct sockaddr_in *sin;
	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 supported\n");
	sd= socket(AF_INET,SOCK_STREAM,0);
	if(sd== -1)
	{
		g_print("create socket error!\n");
		return -1;
	}

	sin= g_new(struct sockaddr_in,1);
	sin->sin_family=AF_INET;
	sin->sin_port=OURPORT;
	slen=sizeof(struct sockaddr_in);
	
	if(bind(sd,sin,slen)< 0)
	{
		g_print("bind erro!\n");
		return -1;
	}

	if(listen(sd,8)<0)
	{
		g_print("listen error!\n");
		return -1;
	}

	for(i=0;i<MAX_USERS;i++)
		user[i].in_use=FALSE;

	flags= fcntl(sd,F_GETFL);
	fcntl(sd,F_SETFL,flags&~O_NDELAY);

	for(;;)
	{
		newsd=accept(sd,sin,&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[i].sd,F_GETFL);
				fcntl(user[i].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(sin);
}

#include<gtk/gtk.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#define OURPORT 8088

gint sd;
struct sockaddr_in s_in;
gchar username[64];
gchar buf[1024];
gchar get_buf[1048];
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 create_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=OURPORT;
	slen=sizeof(s_in);
	if(connect(sd,&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 *button,gpointer data)
{
	create_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;
}

那个多人聊天的代码怎么运行不起来啊我,是哪里出问题了,求指教下哈,服务端总是显示thread not support,我用的是ubuntu14,
你在编译时加入了thread头文件吗?
gcc -o s s.c `pkg-config --cflags --libs glib2-0 gthread-2.0`
gcc -o c c.c `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
头像
mofi
帖子: 35
注册时间: 2012-11-20 15:42
系统: ubuntu/windows7

Re: GTK+2.0 编程范例

#39

帖子 mofi » 2014-05-17 7:50

上面那个聊天室的程序,我在同学系统上也运行不出来,不晓得怎么回事,你们也可以在你们电脑上运行下,测试下,帮忙解决下,谢谢
nae6taiyie0T
帖子: 482
注册时间: 2013-09-13 0:42
系统: Debian sid

Re: GTK+2.0 编程范例

#40

帖子 nae6taiyie0T » 2014-05-17 11:02

mofi 写了:上面那个聊天室的程序,我在同学系统上也运行不出来,不晓得怎么回事,你们也可以在你们电脑上运行下,测试下,帮忙解决下,谢谢
代码有一些问题, 有些接口比较旧.
大致修改了一下, 在debian sid上能正常编译和运行.
Makefile

代码: 全选

CC            = gcc
CXX           = g++
CFLAGS        = -pipe -O2 -Wall -W
CXXFLAGS      = -pipe -O2 -Wall -W
INCPATH       = `pkg-config --cflags gtk+-2.0`
LINK          = gcc
LFLAGS        = -Wl,-O1
LIBS          = `pkg-config --libs gtk+-2.0`
RM            = rm -fv

all:
	$(MAKE) server
	$(MAKE) client

client: client.c
	$(CC) -c $(CFLAGS) $(INCPATH) -o client.o client.c
	$(LINK) $(LFLAGS) -o client client.o $(LIBS)

server: server.c
	$(CC) -c $(CFLAGS) $(INCPATH) -o server.o server.c
	$(LINK) $(LFLAGS) -o server server.o $(LIBS)

.PHONY: clean
clean:
	$(RM) *.o
server.c

代码: 全选

#include<glib.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<netdb.h>
#include<netinet/in.h>

#include "chatroom.h"


struct _client{
  gint sd;
  gboolean in_use;
  gchar name[NAME_SIZE];
  gchar buf[BUF_SIZE];
};
typedef struct _client client;
client users[MAX_USERS];

void do_service(gpointer id) {
  gint j;
  char tobuf[BUF_SIZE];
  gint uid = GPOINTER_TO_INT(id);

  while(read(users[uid].sd, users[uid].buf, BUF_SIZE) != -1) {
    sprintf(tobuf, "%s:%s\n", users[uid].name, users[uid].buf);
    for(j= 0; j < MAX_USERS; j++) {
      if(users[j].in_use) {
        write(users[j].sd,tobuf, BUF_SIZE);
        g_print("%s", tobuf);
      }
    }
  }
  users[uid].in_use = FALSE;
  close(users[uid].sd);
}

int main(int argc, char *argv[]) {
  int sd, newsd;
  struct sockaddr_in sin;
  socklen_t slen;
  gint count = 0;
  gint flags;
  gchar buf[BUF_SIZE];
  gint i;
  
  sd = socket(AF_INET, SOCK_STREAM, 0);
  if(sd == -1) {
    g_print("create socket error!\n");
    return -1;
  }

  sin.sin_family = AF_INET;
  sin.sin_port = OURPORT;
  slen = sizeof(struct sockaddr_in);
  
  if(bind(sd, &sin, slen) < 0) {
    g_print("bind erro!\n");
    return -1;
  }

  if(listen(sd, 8) < 0) {
    g_print("listen error!\n");
    return -1;
  }

  for(i = 0; i < MAX_USERS; i++) {
    users[i].in_use = FALSE;
  }

  flags = fcntl(sd, F_GETFL);
  fcntl(sd, F_SETFL, flags&~O_NDELAY);

  while(TRUE) {
    newsd = accept(sd, &sin, &slen);
    if(newsd == -1) {
      g_print("accept error!\n");
      break;
    } else {
      if(count >= MAX_USERS) {
        sprintf(buf, "用户数量过多服务器不能连接。\n");
        write(newsd, buf, BUF_SIZE);
        close(newsd);
      } else {
        flags = fcntl(users[i].sd, F_GETFL);
        fcntl(users[i].sd, F_SETFL, O_NONBLOCK);
        users[count].sd = newsd;
        users[count].in_use = TRUE;
        read(newsd, users[count].name, NAME_SIZE);
        g_thread_new("do_server",
                     (GThreadFunc)do_service,
                     GINT_TO_POINTER(count));
        count++;
      }
    }
  }
  printf("sd is never closed!\n");
  close(sd);

  return 0;
}
client.c

代码: 全选

#include<gtk/gtk.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#include "chatroom.h"


gint sd;
struct sockaddr_in s_in;
gchar username[NAME_SIZE];
gchar buf[BUF_SIZE];
// FIXME: why 1048?
//gchar get_buf[1048];
gchar get_buf[BUF_SIZE];
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[BUF_SIZE];
   gchar buf[BUF_SIZE];
   while(read(sd, buf, BUF_SIZE) != -1) {
      sprintf(get_buf, "%s", buf);
      // FIXME: all GDK and GTK calls should be made from main thread
      //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_new("get_message", (GThreadFunc)get_message, 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_new("get_message", (GThreadFunc)get_message, NULL);
   }
   // FIXME, declear data as GtkWidget* 
   gtk_widget_destroy(data);
}

void create_win(void) {
   GtkWidget *win, *vbox;
   GtkWidget *button;

   // TODO: Replace this window with a GtkDialog
   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 = OURPORT;
   slen = sizeof(s_in);
   if(connect(sd, &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, NAME_SIZE);
      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, BUF_SIZE);
   gtk_entry_set_text(GTK_ENTRY(message_entry), "");
}

void on_login(GtkWidget *button, gpointer data) {
   create_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;

   gtk_init(&argc, &argv);

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), "客户端");
   gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
   gtk_container_set_border_width(GTK_CONTAINER(window), 5);
   g_signal_connect(G_OBJECT(window), "delete_event",
                    G_CALLBACK(on_delete_event), NULL);

   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, 0);
   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, 0);

   message_entry = gtk_entry_new();
   gtk_box_pack_start(GTK_BOX(hbox), message_entry, TRUE, TRUE, 0);
   g_signal_connect(G_OBJECT(message_entry), "activate",
                    G_CALLBACK(on_send), NULL);

   button = gtk_button_new_with_label("发送");
   gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
   g_signal_connect(G_OBJECT(button), "clicked",
                    G_CALLBACK(on_send), NULL);

   gtk_widget_show_all(window);
   gtk_main();

   return 0;
}
把所有源码都打了包:
gtk2-chatroom.tar.gz
(20 KiB) 已下载 99 次
再附一张客户端的截图:
gtk2-chatroom.png
头像
mofi
帖子: 35
注册时间: 2012-11-20 15:42
系统: ubuntu/windows7

Re: GTK+2.0 编程范例

#41

帖子 mofi » 2014-05-17 14:37

nae6taiyie0T 写了:
mofi 写了:上面那个聊天室的程序,我在同学系统上也运行不出来,不晓得怎么回事,你们也可以在你们电脑上运行下,测试下,帮忙解决下,谢谢
代码有一些问题, 有些接口比较旧.
大致修改了一下, 在debian sid上能正常编译和运行.
Makefile

代码: 全选

CC            = gcc
CXX           = g++
CFLAGS        = -pipe -O2 -Wall -W
CXXFLAGS      = -pipe -O2 -Wall -W
INCPATH       = `pkg-config --cflags gtk+-2.0`
LINK          = gcc
LFLAGS        = -Wl,-O1
LIBS          = `pkg-config --libs gtk+-2.0`
RM            = rm -fv

all:
	$(MAKE) server
	$(MAKE) client

client: client.c
	$(CC) -c $(CFLAGS) $(INCPATH) -o client.o client.c
	$(LINK) $(LFLAGS) -o client client.o $(LIBS)

server: server.c
	$(CC) -c $(CFLAGS) $(INCPATH) -o server.o server.c
	$(LINK) $(LFLAGS) -o server server.o $(LIBS)

.PHONY: clean
clean:
	$(RM) *.o
server.c

代码: 全选

#include<glib.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<sys/time.h>
#include<unistd.h>
#include<netdb.h>
#include<netinet/in.h>

#include "chatroom.h"


struct _client{
  gint sd;
  gboolean in_use;
  gchar name[NAME_SIZE];
  gchar buf[BUF_SIZE];
};
typedef struct _client client;
client users[MAX_USERS];

void do_service(gpointer id) {
  gint j;
  char tobuf[BUF_SIZE];
  gint uid = GPOINTER_TO_INT(id);

  while(read(users[uid].sd, users[uid].buf, BUF_SIZE) != -1) {
    sprintf(tobuf, "%s:%s\n", users[uid].name, users[uid].buf);
    for(j= 0; j < MAX_USERS; j++) {
      if(users[j].in_use) {
        write(users[j].sd,tobuf, BUF_SIZE);
        g_print("%s", tobuf);
      }
    }
  }
  users[uid].in_use = FALSE;
  close(users[uid].sd);
}

int main(int argc, char *argv[]) {
  int sd, newsd;
  struct sockaddr_in sin;
  socklen_t slen;
  gint count = 0;
  gint flags;
  gchar buf[BUF_SIZE];
  gint i;
  
  sd = socket(AF_INET, SOCK_STREAM, 0);
  if(sd == -1) {
    g_print("create socket error!\n");
    return -1;
  }

  sin.sin_family = AF_INET;
  sin.sin_port = OURPORT;
  slen = sizeof(struct sockaddr_in);
  
  if(bind(sd, &sin, slen) < 0) {
    g_print("bind erro!\n");
    return -1;
  }

  if(listen(sd, 8) < 0) {
    g_print("listen error!\n");
    return -1;
  }

  for(i = 0; i < MAX_USERS; i++) {
    users[i].in_use = FALSE;
  }

  flags = fcntl(sd, F_GETFL);
  fcntl(sd, F_SETFL, flags&~O_NDELAY);

  while(TRUE) {
    newsd = accept(sd, &sin, &slen);
    if(newsd == -1) {
      g_print("accept error!\n");
      break;
    } else {
      if(count >= MAX_USERS) {
        sprintf(buf, "用户数量过多服务器不能连接。\n");
        write(newsd, buf, BUF_SIZE);
        close(newsd);
      } else {
        flags = fcntl(users[i].sd, F_GETFL);
        fcntl(users[i].sd, F_SETFL, O_NONBLOCK);
        users[count].sd = newsd;
        users[count].in_use = TRUE;
        read(newsd, users[count].name, NAME_SIZE);
        g_thread_new("do_server",
                     (GThreadFunc)do_service,
                     GINT_TO_POINTER(count));
        count++;
      }
    }
  }
  printf("sd is never closed!\n");
  close(sd);

  return 0;
}
client.c

代码: 全选

#include<gtk/gtk.h>
#include<string.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>

#include "chatroom.h"


gint sd;
struct sockaddr_in s_in;
gchar username[NAME_SIZE];
gchar buf[BUF_SIZE];
// FIXME: why 1048?
//gchar get_buf[1048];
gchar get_buf[BUF_SIZE];
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[BUF_SIZE];
   gchar buf[BUF_SIZE];
   while(read(sd, buf, BUF_SIZE) != -1) {
      sprintf(get_buf, "%s", buf);
      // FIXME: all GDK and GTK calls should be made from main thread
      //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_new("get_message", (GThreadFunc)get_message, 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_new("get_message", (GThreadFunc)get_message, NULL);
   }
   // FIXME, declear data as GtkWidget* 
   gtk_widget_destroy(data);
}

void create_win(void) {
   GtkWidget *win, *vbox;
   GtkWidget *button;

   // TODO: Replace this window with a GtkDialog
   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 = OURPORT;
   slen = sizeof(s_in);
   if(connect(sd, &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, NAME_SIZE);
      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, BUF_SIZE);
   gtk_entry_set_text(GTK_ENTRY(message_entry), "");
}

void on_login(GtkWidget *button, gpointer data) {
   create_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;

   gtk_init(&argc, &argv);

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_window_set_title(GTK_WINDOW(window), "客户端");
   gtk_window_set_default_size(GTK_WINDOW(window), 640, 480);
   gtk_container_set_border_width(GTK_CONTAINER(window), 5);
   g_signal_connect(G_OBJECT(window), "delete_event",
                    G_CALLBACK(on_delete_event), NULL);

   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, 0);
   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, 0);

   message_entry = gtk_entry_new();
   gtk_box_pack_start(GTK_BOX(hbox), message_entry, TRUE, TRUE, 0);
   g_signal_connect(G_OBJECT(message_entry), "activate",
                    G_CALLBACK(on_send), NULL);

   button = gtk_button_new_with_label("发送");
   gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
   g_signal_connect(G_OBJECT(button), "clicked",
                    G_CALLBACK(on_send), NULL);

   gtk_widget_show_all(window);
   gtk_main();

   return 0;
}
把所有源码都打了包:
gtk2-chatroom.tar.gz
再附一张客户端的截图:
gtk2-chatroom.png
我在fedora19中运行服务器端显示bind失败,是不是我少安装了什么程序么,能留个QQ或者邮箱么,我想请教下您,谢谢
头像
mofi
帖子: 35
注册时间: 2012-11-20 15:42
系统: ubuntu/windows7

Re: GTK+2.0 编程范例

#42

帖子 mofi » 2014-05-17 15:22

我在ubuntu14中运行了,可以运行结果,跟您的一样,但是fedota19就不行了,编译也没有报错,运行就显示bind errno
头像
ylkit
帖子: 6
注册时间: 2014-05-16 19:52
系统: Ubuntu 14.04, 32bit

Re: GTK+2.0 编程范例

#43

帖子 ylkit » 2014-05-20 17:52

留存,谢谢分享
头像
sainthsu
帖子: 14
注册时间: 2010-03-01 11:20

Re: GTK+2.0 编程范例

#44

帖子 sainthsu » 2014-06-11 11:11

到底学哪个阿
头像
sainthsu
帖子: 14
注册时间: 2010-03-01 11:20

Re: GTK+2.0 编程范例

#45

帖子 sainthsu » 2014-06-11 11:11

到底学哪个阿
回复