+++GTK界面下的简单聊天工具(linux socket)

GTK界面下的简单聊天工具(linux socket)

基本原理:
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 <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>
#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 <gtk/gtk.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <netdb.h>
#include <glib.h>
#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;
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值