基于socket编程的多人聊天室

  先是做完的效果图:

        

server.c

  1 /* 服务器端 server.c */
  2 #include <glib.h>
  3 #include <stdio.h>
  4 #include <fcntl.h>
  5 #include <signal.h>
  6 #include <sys/socket.h>
  7 #include <sys/types.h>
  8 #include <sys/time.h>
  9 #include <unistd.h>
 10 #include <netdb.h>
 11 #include <netinet/in.h>
 12 #include <arpa/inet.h>
 13 #define MAX_USERS 800   //最大访问人数
 14
 15 //定义用户数据结构
 16 struct _client {
 17    gint sd;
 18    gboolean in_use;
 19    gchar name[64];
 20    gchar buf[1024];
 21             };
 22 typedef struct _client client;
 23
 24 //定义用户数据区
 25 client user[MAX_USERS];
 26 //定义服务线程
 27 void do_service (gpointer id){
 28      gint j;
 29      char tobuf[1024];
 30     while(read(user[GPOINTER_TO_INT(id)].sd,user[GPOINTER_TO_INT(id)].buf,1024)!=-1)
 31     {
 32         sprintf(tobuf,"%s:%s\n",user[GPOINTER_TO_INT(id)].name,
 33         user[GPOINTER_TO_INT(id)].buf);
 34          for(j=0; j<MAX_USERS; j++)        {
 35           if(user[j].in_use)
 36           {
 37             write(user[j].sd,tobuf,1024);
 38             //g_print("%s",tobuf);
 39           }
 40          }
 41     }
 42 //
 43      user[GPOINTER_TO_INT(id)].in_use = FALSE;
 44      close(user[GPOINTER_TO_INT(id)].sd);
 45     exit(0);
 46
 47 }
 48 int main(int argc, char* argv[])
 49 {
 50    gint sd, newsd;
 51    struct sockaddr_in *sin;
 52    gint slen;
 53    gint count = 0;
 54    gint flags;
 55    gchar buf[1024];
 56    gchar tobuf[1024];
 57    gint length,i,j;
 58    if(!g_thread_supported())
 59         g_thread_init(NULL);
 60     else
 61         g_print("thread not supported\n");
 62
 63     sd = socket(AF_INET,SOCK_STREAM,0);   //1.......创建套接子
 64   if(sd == -1)
 65   {
 66       g_print("create socket error!\n");
 67        return -1;
 68   }
 69        sin = g_new(struct sockaddr_in,1);
 70        sin->sin_family = AF_INET;
 71          sin->sin_port = htons(1234);
 72          slen = sizeof(struct sockaddr_in);
 73         sin->sin_addr.s_addr=inet_addr("127.0.0.1");
 74
 75   if(bind(sd,(struct sockaddr*)sin,slen)<0) //2......绑定
 76   {
 77       g_print("bind error!\n");
 78        return -1;
 79   }
 80   if(listen(sd,8)<0)        //3......开启监听
 81   {
 82        g_print("listen error!\n"); return -1;
 83   }
 84   for(i=0; i<MAX_USERS; i++)    //判断访问人数
 85       user[i].in_use = FALSE;
 86       flags = fcntl(sd,F_GETFL);
 87       fcntl(sd,F_SETFL,flags&~O_NDELAY);
 88   for(;;)
 89   {
 90        newsd = accept(sd,sin,&slen); //4....接收
 91       if(newsd == -1){
 92           g_print("accept error!\n");
 93           break;
 94               }
 95     else
 96     {
 97       if(count >= MAX_USERS)
 98       {
 99          sprintf(buf,"用户数量过多服务器不能连接。\n");
100          write(newsd,buf,1024);
101          close(newsd);
102       }
103       else
104       {
105           flags = fcntl(user[i].sd,F_GETFL);
106           fcntl(user[i].sd,F_SETFL,O_NONBLOCK);
107           user[count].sd = newsd;
108           user[count].in_use = TRUE;
109           read(newsd,user[count].name,64);
110         // 创建为用户服务的线程
111          g_thread_create((GThreadFunc)do_service,
112
113         (gpointer)count,TRUE,NULL);
114         count++;
115         }
116       }
117  }//
118     for(;;)
119     close(sd);
120     g_free(sin);
121 } 

client.c

  1 /* 客户端 client.c */
  2 #include <gtk/gtk.h>
  3 #include<stdio.h>
  4 #include<string.h>
  5 #include<stdlib.h>
  6 #include <sys/types.h>
  7 #include <sys/socket.h>
  8 #include <netinet/in.h>
  9 #include</usr/include/mysql/mysql.h>
 10 #define OURPORT 8088 //定义端口号
 11 #define MAXLINE 800
 12
 13 static GtkWidget *text1;
 14 static GtkWidget *text2;
 15 static GtkWidget *login;
 16 static GtkWidget *entry_id;
 17 static GtkWidget *entry_pwd;
 18 static GtkWidget *regwindow;
 19
 20 static GtkWidget *reg_entry1;
 21 static GtkWidget *reg_entry2;
 22
 23 static GtkWidget *window1;//聊天室主窗口
 24 static GtkWidget *win;//昵称登录窗口
 25 static GtkWidget *text_view;
 26
 27 static GtkTextBuffer *buffer; //显示对话内容的文本显示缓冲区
 28 static GtkTextBuffer *buffer1;
 29 static GtkTextBuffer *buffer2;
 30 static GtkWidget *textview1; //显示输入消息的单行录入控件
 31 static GtkWidget *name_entry;//输入用户名的单行录入控件
 32 static GtkWidget *login_button; //登录按钮
 33 void btn_cal_clicked();
 34 void on_send (GtkButton* button, gpointer data) ;
 35 void update_widget_bg(GtkWidget * widget, gchar * img_file);
 36
 37 gint sd; //套接字句柄
 38 struct sockaddr_in s_in; //套接字数据结构
 39 gchar username[64]; //用户名
 40 gchar buf[1024]; //写缓冲区
 41 gchar get_buf[1048]; //读缓冲区
 42 gboolean isconnected = FALSE; // 定义逻辑值表示是否连接
 43
 44 MYSQL_RES *rs;
 45 MYSQL_ROW row;
 46 MYSQL_RES *exe_sql(char sql[MAXLINE])
 47 {
 48     const char *host = "localhost";
 49     const char *user = "root";
 50     const char *pass = "";
 51     const char *db = "talk";
 52
 53     /* 定义mysql变量 */
 54     MYSQL_RES *result;
 55     MYSQL * mysql;
 56     if(!(mysql=mysql_init(NULL)))
 57     {
 58         printf("mysql_init wrong!");
 59         mysql_close(mysql);
 60         exit(0);
 61     }
 62     /* 连接数据库 */
 63     if (!mysql_real_connect(mysql, host, user, pass, db, 3306, NULL, 0))
 64     {
 65         printf("connect wrong!");
 66         mysql_close(mysql);
 67         exit(0);
 68     }
 69     printf("%s\n",sql);
 70     if(mysql_query(mysql,sql))
 71     {
 72         printf("mysql_query_wrong!");
 73         mysql_close(mysql);
 74         exit(0);
 75     }
 76     result = mysql_store_result(mysql);    /* 获取查询结果 */
 77     return result;
 78 }
 79 //socket通信
 80 void get_message(void)
 81 {
 82     GtkTextIter iter;
 83         gchar get_buf[1024];
 84         gchar buf[1024];
 85     while(read(sd,buf,1024) != -1) // 只要读取数据成功就循环执行
 86      {
 87         sprintf(get_buf,"%s",buf);
 88         printf("%s\n",buf);
 89         gdk_threads_enter(); //进入
 90         gtk_text_buffer_get_end_iter(buffer,&iter);
 91         gtk_text_buffer_insert(buffer,&iter,get_buf,-1);//显示读取的数据
 92         gdk_threads_leave(); //离开
 93     }
 94 }
 95 // 连接多人聊天服务器
 96 gboolean do_connect(void)
 97 {
 98     GtkTextIter iter;
 99     gint slen;
100     sd = socket(AF_INET,SOCK_STREAM,0);//创建
101     printf("%d\n",sd);
102     if(sd < 0)
103     {
104         gtk_text_buffer_get_end_iter(buffer,&iter);
105         gtk_text_buffer_insert(buffer,&iter,"打开套接字时出错!\n",-1);
106     return FALSE;
107     }
108     s_in.sin_family = AF_INET;
109     s_in.sin_port = htons(1234);
110     slen = sizeof(s_in);
111     if(connect(sd,&s_in,slen) < 0) //
112     {
113         gtk_text_buffer_get_end_iter(buffer,&iter);
114         gtk_text_buffer_insert(buffer,&iter,"连接服务器时出错!\n",-1);
115         return FALSE;
116     }
117     else
118     {
119
120         gtk_text_buffer_get_end_iter(buffer,&iter);
121         gtk_text_buffer_insert(buffer,&iter,username,-1);
122         gtk_text_buffer_get_end_iter(buffer,&iter);
123         gtk_text_buffer_insert(buffer,&iter,"\n成功与服务器连接....\n",-1);
124         //
125         write(sd,username,64);//向服务器发送用户名//
126         isconnected = TRUE;
127         return TRUE;
128      }
129 }
130 void on_send (GtkButton* button, gpointer data)
131 {
132     //向服务器发送数据
133     const char* message;
134     GtkTextIter start;
135     GtkTextIter end;
136     char sql[MAXLINE];
137      if(isconnected==FALSE)
138         return;
139     buffer1=gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview1));
140     gtk_text_buffer_get_start_iter(buffer1,&start);
141     gtk_text_buffer_get_end_iter(buffer1,&end);
142     message=gtk_text_buffer_get_text(buffer1,&start,&end,TRUE);
143     sprintf(buf,"%s\n",message);
144     write(sd,buf,1024);//发送
145     sprintf(sql,"insert into history (user,message,date) values (‘%s‘,‘%s‘,now())",username,message);
146
147     rs = exe_sql(sql);
148     gtk_text_buffer_set_text(buffer1,"",-1);////清除文字
149
150 }
151 void on_login(GtkWidget *button, gpointer data)
152 {
153     //点击登录按钮时执行
154     create_win();
155 }
156 void cls()//清屏
157 {
158     gtk_text_buffer_set_text(buffer,"",-1);
159 }
160 void history()
161 {
162     int rows_num;
163     int count;
164     GtkBuilder *gb;
165     //查看历史窗口
166     GtkWidget *history_win;//查看聊天历史界面
167     GtkWidget *history_view;
168     char *sql[MAXLINE];
169     gb=gtk_builder_new();
170     gtk_builder_add_from_file(gb,"history.glade",NULL);
171     history_win=GTK_WIDGET(gtk_builder_get_object(gb,"history_win"));
172     history_view=GTK_WIDGET(gtk_builder_get_object(gb,"history_view"));
173     update_widget_bg(history_win, "ico/bg.jpg");
174     gtk_widget_show(GTK_WIDGET(history_win));
175     //显示数据
176     strcpy(sql,"select * from history where date <=now() and date >=now()-interval 5 minute");
177     rs=exe_sql(sql);
178     printf("%s\n",sql);
179     rows_num=mysql_num_rows(rs);
180
181     for(count=0;count<rows_num;count++)
182     {
183         GtkTextIter end;
184         row=mysql_fetch_row(rs);
185         buffer1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(history_view));
186         gtk_text_buffer_get_end_iter(buffer1,&end);
187         gtk_text_buffer_insert(buffer1, &end, row[1], -1);
188         gtk_text_buffer_insert(buffer1, &end, " : ", -1);
189         gtk_text_buffer_insert(buffer1, &end, row[2], -1);
190         gtk_text_buffer_insert(buffer1, &end, "  ", -1);
191         gtk_text_buffer_insert(buffer1, &end, row[3], -1);
192         gtk_text_buffer_insert(buffer1, &end, "\n", -1);
193
194     }
195 }
196 //当点击登录窗口的登录按钮时执行
197 void on_button_clicked(GtkButton *button, gpointer data)
198 {
199       buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
200     gtk_text_buffer_set_text(buffer, "Hello    ", -1);
201     gchar *name;
202     name = gtk_entry_get_text(GTK_ENTRY(name_entry));
203
204     sprintf(username,"%s",name);
205
206     if(do_connect())
207     {
208         gtk_widget_set_sensitive(login_button,FALSE);
209         g_thread_create((GThreadFunc)get_message,NULL,FALSE,NULL);
210     }
211         gtk_widget_destroy(data);
212     }
213
214 //当前关闭登录窗口时执行
215 void on_destroy(GtkWidget *widget, GdkEvent *event, gpointer data)
216 {
217     sprintf(username,"guest");
218     if(do_connect()==TRUE)
219     {
220         gtk_widget_set_sensitive(login_button,FALSE);
221         g_thread_create((GThreadFunc)get_message,NULL,FALSE,NULL);
222     }
223     gtk_widget_destroy(widget);
224 }
225 //背景图片的显示功能
226 void update_widget_bg(GtkWidget * widget, gchar * img_file)
227 {
228     GtkStyle *style;
229     GdkPixbuf *pixbuf;
230     GdkPixmap *pixmap;
231     gint width, height;
232
233     pixbuf = gdk_pixbuf_new_from_file(img_file, NULL);
234     width = gdk_pixbuf_get_width(pixbuf);
235     height = gdk_pixbuf_get_height(pixbuf);
236     pixmap = gdk_pixmap_new(NULL, width, height, 24);
237     gdk_pixbuf_render_pixmap_and_mask(pixbuf, &pixmap, NULL, 0);
238     style = gtk_style_copy(GTK_WIDGET(widget)->style);
239     if (style->bg_pixmap[GTK_STATE_NORMAL])
240         g_object_unref(style->bg_pixmap[GTK_STATE_NORMAL]);
241     style->bg_pixmap[GTK_STATE_NORMAL] = g_object_ref(pixmap);
242     style->bg_pixmap[GTK_STATE_ACTIVE] = g_object_ref(pixmap);
243     style->bg_pixmap[GTK_STATE_PRELIGHT] = g_object_ref(pixmap);
244     style->bg_pixmap[GTK_STATE_SELECTED] = g_object_ref(pixmap);
245     style->bg_pixmap[GTK_STATE_INSENSITIVE] = g_object_ref(pixmap);
246     gtk_widget_set_style(GTK_WIDGET(widget), style);
247     g_object_unref(style);
248 }
249 void btn_cal(GtkWidget *dialog,gpointer data)
250 {
251     gtk_widget_destroy(win);
252     return FALSE;
253 }
254 void create_win(void)
255 {     //昵称窗口
256     GtkBuilder *gb;
257     GtkWidget *btn_ok;
258     gb=gtk_builder_new();
259     gtk_builder_add_from_file(gb,"log.glade",NULL);
260         win=GTK_WIDGET(gtk_builder_get_object(gb,"win"));
261     name_entry=GTK_WIDGET(gtk_builder_get_object(gb,"name_entry"));
262     btn_ok=GTK_WIDGET(gtk_builder_get_object(gb,"btn_ok"));
263     update_widget_bg(win, "ico/bg.jpg");
264     gtk_widget_show(GTK_WIDGET(win));
265     g_signal_connect(GTK_OBJECT(btn_ok),"clicked",G_CALLBACK(on_button_clicked),win);
266 }
267 //聊天室关闭按钮
268 void button1_clicked()
269 {
270     close(sd);//关闭
271     gtk_main_quit();
272 }
273 /* 弹出对话框代码开始*/
274 void show_info(char *msgtip)
275 {
276     GtkWidget *dialog;
277     dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msgtip);
278     gtk_window_set_title(GTK_WINDOW(dialog), "Information");
279     gtk_dialog_run(GTK_DIALOG(dialog));
280     gtk_widget_destroy(dialog);
281 }
282 /*glade主界面*/
283 #define w_(builder,type,name) name=GTK_##type(gtk_builder_get_object(builder,#name))
284 GtkBuilder* gtk_load_glade(gchar* filename)
285
286 {
287
288   GtkBuilder *gb;
289
290   gb=gtk_builder_new();
291
292   if(!gtk_builder_add_from_file(gb,filename,NULL))
293       return NULL;
294
295   gtk_builder_connect_signals(gb,NULL);
296
297   return gb;
298
299 }
300 void cal_widget_init()
301
302 {
303
304   gtk_widget_show(GTK_WIDGET(window1));
305
306 }
307
308 void cal_get_widgets(GtkBuilder* gb)
309
310 {
311
312   w_(gb,WINDOW,login);
313
314   w_(gb,ENTRY,entry_id);
315   w_(gb,ENTRY,entry_pwd);
316
317   w_(gb,WINDOW,window1);
318
319   w_(gb,TEXT_VIEW,text_view);
320   w_(gb,WIDGET,textview1);
321   w_(gb,ENTRY,name_entry);
322
323 }
324 //登录按钮的响应函数
325 void mysql_connect()
326 {
327     char sql[MAXLINE];
328     const gchar *entry1;
329     const gchar *entry2;
330     entry1=gtk_entry_get_text(GTK_ENTRY(entry_id));
331     entry2=gtk_entry_get_text(GTK_ENTRY(entry_pwd));
332
333     if (strcmp(entry1, "") == 0) {
334         show_info("帐号不能为空!");
335         return;
336     }
337     if (strcmp(entry2, "") == 0) {
338         show_info("密码不能为空!");
339         return;
340     }
341
342     sprintf(sql,"select count(*) from users where user=‘%s‘ and passwd=‘%s‘",entry1,entry2);
343
344     rs=exe_sql(sql);
345
346         row=mysql_fetch_row(rs);
347
348     const gchar *a=row[0];
349
350     if(strcmp(a,"1")==0)
351         {
352             show_info("成功登录!");
353              if(!g_thread_supported())
354             g_thread_init(NULL);
355             //初始线程
356
357               GtkBuilder *gb;
358
359               gb=gtk_load_glade("try1.glade");
360             gtk_widget_destroy(login);
361             if(gb==NULL)
362             return -1;
363
364               cal_get_widgets(gb);
365
366               cal_widget_init();
367             return 0;
368         }
369     else
370
371         show_info("用户名或密码失败\n");
372         return;
373 }
374 //创建button按钮
375 GtkWidget *create_button()
376 {
377     GtkWidget *button = gtk_button_new();
378     return button;
379 }
380 //退出按钮
381 void btn_cal_clicked(GtkWidget *dialog,gpointer data)
382 {
383     gtk_widget_destroy(regwindow);
384     return FALSE;
385 }
386 //注册的响应函数
387 void reg_btn2_clicked()
388 {
389     int rows;
390     MYSQL_ROW *mysql_row;
391     const char *name=gtk_entry_get_text(GTK_ENTRY(reg_entry1));
392     const char *passwd=gtk_entry_get_text(GTK_ENTRY(reg_entry2));
393     if (strcmp(name, "") == 0)
394     {
395         show_info("帐号不能为空!");
396         return;
397     }
398     if (strcmp(passwd, "") == 0)
399     {
400         show_info("密码不能为空!");
401         return;
402     }
403     char sql[MAXLINE];
404     char query[MAXLINE];
405     sprintf(query,"select * from users where user=‘%s‘",name);
406     rs = exe_sql(query);
407     rows=mysql_num_rows(rs);
408     //mysql_row=mysql_fetch_row(rs);
409     //const gchar *b=row[0];
410
411     if(rows>=1)
412     {
413         show_info("用户名已被注册\n");
414         return;
415     }
416     else
417     sprintf(sql, "insert into users(user,passwd) values(‘%s‘,‘%s‘)",name,passwd);
418     rs = exe_sql(sql);
419     show_info("注册成功");
420 }
421 //注册响应函数+注册界面
422 void btn_reg_clicked()
423 {
424     GtkBuilder *gb;
425     GtkWidget *reg_btn1;
426     GtkWidget *reg_btn2;
427     gb=gtk_builder_new();
428     gtk_builder_add_from_file(gb,"reg.glade",NULL);
429         regwindow=GTK_WIDGET(gtk_builder_get_object(gb,"regwindow"));
430     reg_entry1=GTK_WIDGET(gtk_builder_get_object(gb,"reg_entry1"));
431     reg_entry2=GTK_WIDGET(gtk_builder_get_object(gb,"reg_entry2"));
432     reg_btn1=GTK_WIDGET(gtk_builder_get_object(gb,"reg_btn1"));
433     reg_btn2=GTK_WIDGET(gtk_builder_get_object(gb,"reg_btn2"));
434     update_widget_bg(regwindow, "ico/bg.jpg");
435     gtk_widget_show(GTK_WIDGET(regwindow));
436     g_signal_connect(GTK_OBJECT(reg_btn1),"clicked",G_CALLBACK(btn_cal_clicked),regwindow);
437     g_signal_connect(GTK_OBJECT(reg_btn2),"clicked",G_CALLBACK(reg_btn2_clicked),regwindow);
438 }
439 GtkWidget *create_window() //创建窗体和控件!!
440 {
441     gtk_init(NULL, NULL); //初始化
442       GtkBuilder *gb;
443
444       gb=gtk_load_glade("client.glade");
445
446       cal_get_widgets(gb);
447       update_widget_bg(login, "ico/bg.jpg");
448
449       gtk_widget_show_all(login); //显示窗体和控件
450       return 0;
451 }
452 int main(int argc,char *argv[])
453 {
454
455     create_window(); //创建窗体和控件!!
456     gtk_main(); //事件循环处理
457     return 0;
458 }

由于编写时调用了glade界面和mysql数据库,界面和表就不再上传了。

时间: 2024-10-13 16:08:41

基于socket编程的多人聊天室的相关文章

Linux下基于Socket网络通信的多人聊天室

服务端 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <string.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> cha

使用node.js和socket.io实现多人聊天室

刚学node.js,想着做点东西练练手.网上的东西多而杂,走了不少弯路,花了一天时间在调代码上.参考网上的一篇文章,重写了部分代码,原来的是基于基于node-websocket-server框架的,我没用框架,单单是socket.io. 一.基本功能 1.用户随意输入一个昵称即可登录2.登录成功后1) 对正在登录用户来说,罗列所有在线用户列表,罗列最近的历史聊天记录2) 对已登录的用户来说,通知有新用户进入房间,更新在线用户列表3.退出登录1)支持直接退出2) 当有用户退出,其他所有在线用户会收

nodejs 实例 使用 Express + Socket.IO 搭建多人聊天室

https://cnodejs.org/topic/51d51cd8d44cbfa3047926ba 作者 nswbmw 详细内容大家可以看这个. 由于时间久远,很多代码都过期了.我刚更新了app.js代码. /** * Module dependencies. */ var express = require('express') , http = require('http') , path = require('path'); var app = express(); // all env

基于C/S模式的简易聊天室

一.任务简要描述 移动互联网技术的广泛应用为人们提供了非常便捷的沟通方式.QQ.微信和微博等是便携式聊天系统的典型代表,它们的功能非常强大. 本系统利用TCP/IP协议的Socket和ServerSocket类,实现基于C/S模式的简易聊天室.该聊天室包括服务端和客户端两部分,服务端是客户端发送消息的中转站:客户端之间可以直接通信,也可以与服务器通信.聊天结束后客户端断开与服务端的连接,服务器也可以停止信息中转服务. 二.系统需求分析 本系统采用C/S软件架构,服务器端负责监听客户端发来的消息,

C 基于UDP实现一个简易的聊天室

引言 本文是围绕Linux udp api 构建一个简易的多人聊天室.重点看思路,帮助我们加深 对udp开发中一些api了解.相对而言udp socket开发相比tcp socket开发注意的细节要少很多. 但是水也很深. 本文就当是一个demo整合帮助开发者回顾和继续了解 linux udp开发的基本流程. 首先我们来看看 linux udp 和 tcp的异同. /* 这里简单比较一下TCP和UDP在编程实现上的一些区别: TCP流程 建立一个TCP连接需要三次握手,而断开一个TCP则需要四个

android asmack 注册 登陆 聊天 多人聊天室 文件传输

XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的,最早是在Jabber上实现的.它继承了在XML环境中灵活的发展性.因此,基于XMPP的应用具有超强的可扩展性.并且XML很易穿过防火墙,所以用XMPP构建的应用不易受到防火墙的阻碍.利用XMPP作为通用的传输机制,不同组织内的不同应用都可以进行有效的通信. 这篇文章有基本的介绍,http://bl

Android 基于XMPP Smack openfire 开发的聊天室

Android基于XMPP Smack openfire 开发的聊天室

Spring整合DWR comet 实现无刷新 多人聊天室

用dwr的comet(推)来实现简单的无刷新多人聊天室,comet是长连接的一种.通常我们要实现无刷新,一般会使用到Ajax.Ajax 应用程序可以使用两种基本的方法解决这一问题:一种方法是浏览器每隔若干秒时间向服务器发出轮询以进行更新,另一种方法是服务器始终打开与浏览器的连接并在数据可用时发送给浏览器.第一种方法一般利用setTimeout或是setInterval定时请求,并返回最新数据,这无疑增加了服务器的负担,浪费了大量的资源.而第二种方法也会浪费服务器资源,长期的建立连接:而相对第一种

Java网络编程 - 基于UDP协议 实现简单的聊天室程序

最近比较闲,一直在抽空回顾一些Java方面的技术应用. 今天没什么事做,基于UDP协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对Java网络编程方面的一个简单回忆. 先看一下效果: 实现的效果可以说是非常非常简单,但还是可以简单的看到一个实现原理. "聊天室001"的用户,小红和小绿相互聊了两句,"聊天室002"的小黑无人理会,在一旁寂寞着. 看一下代码实现: 1.首先是消息服务器的实现,功能很简单: 将客户端的信息(进入了哪一个聊