Chinaunix首页 | 论坛 | 博客
  • 博客访问: 89403
  • 博文数量: 27
  • 博客积分: 586
  • 博客等级: 二等列兵
  • 技术积分: 210
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-15 17:55
文章分类
文章存档

2013年(1)

2012年(26)

分类:

2012-12-03 18:22:44

基本原理:
1,基于GTK设计的界面。可以使用glade工具便捷,但是我用不好。
2,C/S都是运用到GTK多线程的思想,主要是为了避免accept,read,write阻塞考虑。新办法我还在学习。
3,注意如果是在终端编译,记得加上`pkg -config --cflags --libs gtk+-2.0 gthread-2.0`。如果是用集成环境记得编译时加参数
4,几个多线程的函数:gdk_threads_enter();gdk_threads_leave();g_thread_create()

5,几个截图


源代码:client.c参考书籍《GTk2.0编程范例》,server.c我自己写。没什么注释见谅!

/*-------------------------server.c----------------------*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 8080
struct sockaddr_in server_addr,client_addr;
int server_fd,client_fd,addr_size=sizeof(client_addr);
char sendbuf[1024],getbuf[1024],username[64]="server";
gboolean isconnected = FALSE;
GtkWidget *text;
GtkTextBuffer *buffer;
GtkWidget *message_entry;
GtkWidget *openbutton;
GtkWidget *closebutton;
void get_message(void)
{
GtkTextIter iter;
memset(&getbuf,0,sizeof(getbuf));
while(read(client_fd,getbuf,1024)!=-1)
{
gdk_threads_enter();
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"client: ",-1);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,getbuf,-1);
gdk_threads_leave();
}
}
void listen_client(void)
{
GtkTextIter iter;
listen (server_fd,1);
client_fd=accept(server_fd,(struct sockaddr *)&client_addr,&addr_size);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"客户端连接!",-1);
isconnected=TRUE;
g_thread_create((GThreadFunc)get_message,NULL,FALSE,NULL);
//这里要配发新进程,不然直接阻塞,窗口卡死
}
void openbutton_clicked(GtkButton *button,gpointer data)
{
gtk_widget_set_sensitive(openbutton,FALSE);//开启按钮失效
server_fd=socket(AF_INET,SOCK_STREAM,0);
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(myport);
server_addr.sin_addr.s_addr=INADDR_ANY;
bind(server_fd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr));
g_thread_create((GThreadFunc)listen_client,NULL,FALSE,NULL);

}

void on_delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{
close(server_fd);
close(client_fd);
gtk_main_quit();
}

void on_send (GtkButton * button,gpointer data)
{
char *message;GtkTextIter iter;
if(isconnected==FALSE) return;
message=gtk_entry_get_text(GTK_ENTRY(message_entry));
memset(&sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"%s\n",message);
write(client_fd,sendbuf,1024);
gtk_entry_set_text(GTK_ENTRY(message_entry),"");
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"server: ",-1);
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,sendbuf,-1);
}

int main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *vbox,*hbox,*label,*view,*button;
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);
openbutton=gtk_button_new_with_label("开启");
gtk_box_pack_start(GTK_BOX(hbox),openbutton,FALSE,FALSE,5);
g_signal_connect(G_OBJECT(openbutton),"clicked",G_CALLBACK(openbutton_clicked),NULL);

closebutton=gtk_button_new_with_label("关闭");
gtk_box_pack_start(GTK_BOX(hbox),closebutton,FALSE,FALSE,5);
g_signal_connect(G_OBJECT(closebutton),"clicked",G_CALLBACK(on_delete_event),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;
}

/*------------------client.c------------------------*/

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define myport 8080

int server_fd;
struct sockaddr_in server_addr;
char sendbuf[1024],getbuf[1024],username[64];
gboolean isconnected = FALSE;
GtkWidget *text;
GtkTextBuffer *buffer;
GtkWidget *message_entry;
GtkWidget *name_entry;
GtkWidget *login_button;

void get_message(void)
{
GtkTextIter iter;
memset(&getbuf,0,sizeof(getbuf));
while(read(server_fd,getbuf,1024)!=-1)
{
gdk_threads_enter();
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,getbuf,-1);
gdk_threads_leave();
}
}
gboolean do_connect (void)
{
GtkTextIter iter;
int len=sizeof(server_addr);
server_fd=socket(AF_INET,SOCK_STREAM,0);
if(server_fd==-1)
{
gtk_text_buffer_get_end_iter(buffer,&iter);
gtk_text_buffer_insert(buffer,&iter,"打开套接字时出错!\n",-1);
return FALSE;
}
memset(&server_addr,0,sizeof(server_addr));

server_addr.sin_family=AF_INET;
server_addr.sin_port=htons(myport);
server_addr.sin_addr.s_addr=inet_addr("192.168.78.128");

if(connect(server_fd,(struct sockaddr*)&server_addr,len)==-1)

{
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(server_fd,username,64);

isconnected= TRUE;
return TRUE;

}
}
void on_send (GtkButton * button,gpointer data)
{
char *message;GtkTextIter iter;
if(isconnected==FALSE) return;
message=gtk_entry_get_text(GTK_ENTRY(message_entry));
memset(&sendbuf,0,sizeof(sendbuf));
sprintf(sendbuf,"%s\n",message);

write(server_fd,sendbuf,1024);
gtk_entry_set_text(GTK_ENTRY(message_entry),"");

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,sendbuf,-1);
}
void on_destory(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)
{
char *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_destory),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);
}

void on_login(GtkWidget *button,gpointer data)
{
create_win();
}

void on_delete_event(GtkWidget *widget,GdkEvent *event,gpointer data)
{
close(server_fd);
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("点击登录按钮连接服务器");
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;
}

SLA:http://hi.baidu.com/hellosim/blog/item/7af95b3478b02808eac4af53.html

阅读(1802) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~