您的位置:程序门 -> .net技术 -> j#



socket2


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


socket2
发表于:2007-09-06 00:27:58 楼主
using   system;
using   system.collections;
using   system.collections.specialized;
using   system.componentmodel;
using   system.data;
using   system.drawing;
using   system.text;
using   system.net.sockets;
using   system.windows.forms;
using   system.threading;
using   system.runtime.serialization;
using   system.runtime.interopservices;
using   system.io;
using   system.runtime.serialization.formatters.binary;
using   system.media;

namespace   easychat
{
        public   partial   class   chat_frm   :   form
        {

                #region   私有字段

                ///   <summary>
                ///   当前用户名
                ///   </summary>
                private   string   _username   =   null;

                ///   <summary>
                ///   数据缓冲区大小
                ///   </summary>
                private   int   _maxpacket   =   2048;

                ///   <summary>
                ///   用于接受消息的线程
                ///   </summary>
                private   thread   _receivethread   =   null;

                ///   <summary>
                ///   用于接受和发送的网络流,从登录窗体得到
                ///   </summary>
                private   networkstream   _nws   =   null;

                ///   <summary>
                ///   服务器套接字的字符串形式,从登录窗体得到
                ///   </summary>
                private   string   _svrskt   =   null;

                ///   <summary>
                ///   播放消息提示的播放器
                ///   </summary>
                private   soundplayer   _sp1   =   new   soundplayer(properties.resources.msg);
                private   soundplayer   _sp2   =   new   soundplayer(properties.resources.nudge);
                ///   <summary>
                ///   指示是否最小化到托盘
                ///   </summary>
                private   bool   _hideflag   =   false;

                #endregion


                #region   聊天窗体构造函数

                ///   <summary>
                ///   构造函数,得到登录窗体的一些信息
                ///   </summary>
                ///   <param   name= "username "> 当前用户名 </param>
                ///   <param   name= "nws "> 接受和发送消息的网络流 </param>
                ///   <param   name= "svrskt "> 服务器套接字的字符串形式 </param>
                public   chat_frm(string   username,   networkstream   nws,   string   svrskt)
                {
                        initializecomponent();
                        _username   =   username;
                        _nws   =   nws;
                        _svrskt   =   svrskt;
                }

                #endregion


                #region   聊天窗体的私有方法

                ///   <summary>
                ///   保存聊天记录
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   save_btn_click(object   sender,   eventargs   e)
                {
                        dialogresult   ret;
                        savefiledialog   sfd   =   new   savefiledialog();
                        sfd.filter   =   "文本文件(*.txt) ¦*.txt ";
                        sfd.addextension   =   true;
                        if   ((ret   =   sfd.showdialog())   ==   dialogresult.ok)
                        {
                                chatrcd_rtb.savefile(sfd.filename,   richtextboxstreamtype.plaintext);
                        }
                }

                ///   <summary>
                ///   清除聊天记录
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   clear_btn_click(object   sender,   eventargs   e)
                {
                        dialogresult   ret;
                        ret   =   messagebox.show( "确定清除吗?清除后不可恢复。 ",  
                                                                    "提示 ",
                                                                    messageboxbuttons.okcancel,
                                                                    messageboxicon.question,  
                                                                    messageboxdefaultbutton.button2);

                        if   (ret   ==   dialogresult.ok)
                        {
                                chatrcd_rtb.clear();
                        }
                }

                ///   <summary>
                ///   向服务器发送离线请求,结束接受消息线程,清理资源并关闭父窗体和自身窗体
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   close_btn_click(object   sender,   eventargs   e)
                {
                        dialogresult   ret;
                        ret   =   messagebox.show( "确定与服务器断开连接吗? ",  
                                                                    "退出 ",
                                                                    messageboxbuttons.okcancel,
                                                                    messageboxicon.question,
                                                                    messageboxdefaultbutton.button2);

                        if   (ret   ==   dialogresult.ok)
                        {
                                //向服务器发送离线请求
                                _nws.write(new   byte[]   {   0,   1   },   0,   2);
                                //结束接受消息的线程
                                if   (_receivethread   !=   null)
                                {
                                        _receivethread.abort();
                                }
                                //关闭网络流
                                _nws.close();
                                //关闭父窗口及自身
                                this.owner.close();
                                this.close();
                        }
                }

                ///   <summary>
                ///   提取命令
                ///   格式为两个一位整数拼接成的字符串。
                ///   第一位为0表示客户机向服务器发送的命令,为1表示服务器向客户机发送的命令。
                ///   第二位表示命令的含义,具体如下:
                ///   "11 "-服务器要求客户机更新在线列表
                ///   "12 "-服务器要求客户机做闪屏振动
                ///   default-接受用户消息或者系统消息的正文
                ///   </summary>
                ///   <param   name= "s "> 要解析的包含命令的byte数组,只提取前两个字节 </param>
                ///   <returns> 拼接成的命令 </returns>
                private   string   decodingbytes(byte[]   s)
                {
                        return   string.concat(s[0].tostring(),   s[1].tostring());
                }
发表于:2007-09-06 00:28:301楼 得分:0
///   <summary>
                ///   接受消息的线程执行体
                ///   </summary>
                private   void   receivemsg()
                {
                        while   (true)
                        {
                                byte[]   packet   =   new   byte[_maxpacket];
                                _nws.read(packet,   0,   packet.length);
                                string   _cmd   =   decodingbytes(packet);

                                switch   (_cmd)
                                {
                                        ///   "11 "-服务器要求客户机更新在线列表
                                        ///   "12 "-服务器要求客户机做闪屏振动
                                        ///   default-接受用户消息或者系统消息的正文
                                        case   "11 ":
                                                {
                                                        byte[]   onlinebuff   =   new   byte[_maxpacket];
                                                        int   bytecnt   =   _nws.read(onlinebuff,   0,   onlinebuff.length);
                                                        iformatter   format   =   new   binaryformatter();
                                                        memorystream   stream   =   new   memorystream();
                                                        stream.write(onlinebuff,   0,   bytecnt);
                                                        stream.position   =   0;
                                                        stringcollection   onlinelist   =   (stringcollection)format.deserialize(stream);
                                                        online_cb.items.clear();
                                                        foreach   (string   onliner   in   onlinelist)
                                                        {
                                                                if   (!onliner.equals(_username))
                                                                {
                                                                        online_cb.items.add(onliner);
                                                                }
                                                        }
                                                        break;
                                                }
                                        case   "12 ":
                                                {
                                                        nudge();
                                                        break;
                                                }
                                        default:
                                                {
                                                        string   displaytxt   =   encoding.unicode.getstring(packet);
                                                        chatrcd_rtb.appendtext(displaytxt);
                                                        _sp1.play();
                                                        break;
                                                }
                                }
                        }
                }

                ///   <summary>
                ///   启动接受消息线程并显示相关信息
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   chat_frm_load(object   sender,   eventargs   e)
                {
                        _receivethread   =   new   thread(new   threadstart(receivemsg));
                        _receivethread.start();
                        online_cb.enabled   =   false;
                        user_lb.text       =   "当前用户: "   +   _username;
                        svrskt_lb.text   =   "服务器: "   +   _svrskt;
                }

                ///   <summary>
                ///   通过窗体右上角关闭窗体
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   chat_frm_formclosing(object   sender,   formclosingeventargs   e)
                {
                        if   (e.closereason   ==   closereason.userclosing)
                        {
                                e.cancel   =   true;
                        }
                        if   (e.closereason   ==   closereason.formownerclosing)
                        {
                                return;
                        }
                        close_btn_click(sender,   e);
                }
发表于:2007-09-06 00:28:552楼 得分:0
///   <summary>
                ///   发送消息,将接受方用户名和消息正文分开发送,便于服务器端处理
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   send_btn_click(object   sender,   eventargs   e)
                {
                        string   localtxt   =   null;
                        string   sendtxt   =   null;
                        string   msg   =   msg_tb.text.trim();
                        if   (msg   ==   string.empty)
                        {
                                messagebox.show( "不能发送空消息 ",
                                                                "提示 ",
                                                                messageboxbuttons.ok,
                                                                messageboxicon.information);
                                return;
                        }

                        //如果是聊天室模式则向服务器发送广播请求
                        if   (broadcast_rb.checked)
                        {
                                localtxt   =   string.format( "[广播]您在   {0}   对所有人说:\r\n{1}\r\n\r\n ",   datetime.now,   msg);
                                sendtxt     =   string.format( "[广播]{0}   在   {1}   对所有人说:\r\n{2}\r\n\r\n ",   _username,   datetime.now,   msg);
                                //发送广播请求
                                _nws.write(new   byte[]   {   0,   5   },   0,   2);
                        }
                        else
                        {
                                string   _receiver   =   online_cb.text;
                                if   (_receiver   ==   string.empty)
                                {
                                        messagebox.show( "请选择一个接收者!\n如果没有接受者可选,表明当前只有您一个人在线\t ",
                                                                        "发送消息 ",
                                                                        messageboxbuttons.ok,
                                                                        messageboxicon.information);
                                        return;
                                }
                                localtxt   =   string.format( "[私聊]您在   {0}   对   {1}   说:\r\n{2}\r\n\r\n ",   datetime.now,   _receiver,   msg);
                                sendtxt     =   string.format( "[私聊]{0}   在   {1}   对您说:\r\n{2}\r\n\r\n ",   _username,   datetime.now,   msg);
                                //发送接受者用户名
                                _nws.write(encoding.unicode.getbytes(_receiver),   0,   encoding.unicode.getbytes(_receiver).length);
                        }
                        _nws.write(encoding.unicode.getbytes(sendtxt),   0,   encoding.unicode.getbytes(sendtxt).length);

                        chatrcd_rtb.appendtext(localtxt);
                        msg_tb.clear();
                }

                ///   <summary>
                ///   有新消息来时闪烁任务栏并且保持聊天记录内容滚动到最底端,qq就是这么玩滴~
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                [dllimport( "user32.dll ")]
                public   static   extern   bool   flashwindow(intptr   hwnd,   bool   binvert);
                private   void   chatrcd_rtb_textchanged(object   sender,   eventargs   e)
                {
                        chatrcd_rtb.scrolltocaret();
                        if   (this.windowstate   ==   formwindowstate.minimized)
                        {
                                flashwindow(this.handle,   true);
                        }
                }

                ///   <summary>
                ///   当窗口恢复后取消任务栏的闪烁效果
                ///   当窗口最小化时判断是否要隐藏到系统托盘
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   chat_frm_sizechanged(object   sender,   eventargs   e)
                {
                        switch   (this.windowstate)
                        {
                                case   formwindowstate.normal:
                                        flashwindow(this.handle,   false);
                                        break;
                                case   formwindowstate.minimized:
                                        if   (_hideflag)
                                        {
                                                notifyicon1.visible   =   true;
                                                this.visible   =   false;
                                        }
                                        break;
                                default:
                                        break;
                        }
                }

                ///   <summary>
                ///   在线列表下拉框显示之前向服务器发送请求在线列表的命令
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   online_cb_dropdown(object   sender,   eventargs   e)
                {
                        _nws.write(new   byte[]   {   0,   2   },   0,   2);
                }

                ///   <summary>
                ///   聊天模式改变
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   broadcast_rb_checkedchanged(object   sender,   eventargs   e)
                {
                        if   (private_rb.checked)
                        {
                                online_cb.enabled   =   true;
                        }
                        else
                        {
                                online_cb.enabled   =   false;
                        }
                }

                ///   <summary>
                ///   设置最小化到系统托盘的标记值
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   hide_cb_checkedchanged(object   sender,   eventargs   e)
                {
                        _hideflag   =   hide_cb.checked;
                }
发表于:2007-09-06 00:29:193楼 得分:0
///   <summary>
                ///   产生闪屏振动效果
                ///   </summary>
                private   void   nudge()
                {
                        if   (notifyicon1.visible   ==   true)
                        {
                                return;
                        }
                        if   (this.windowstate   ==   formwindowstate.minimized)
                        {
                                this.windowstate   =   formwindowstate.normal;
                        }
                        int   i   =   0;
                        point   _old   =   this.location;
                        point   _new1   =   new   point(_old.x   +   2,   _old.y   +   2);
                        point   _new2   =   new   point(_old.x   -   2,   _old.y   -   2);
                        _sp2.play();
                        while   (i   <   4)
                        {
                                this.location   =   _new1;
                                thread.sleep(60);
                                this.location   =   _new2;
                                thread.sleep(60);
                                i++;
                        }
                        this.location   =   _old;
                }

                ///   <summary>
                ///   发送闪屏振动
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   nudge_pb_click(object   sender,   eventargs   e)
                {
                        string   displaytxt   =   null;
                        if   (private_rb.checked   &&   online_cb.text   ==   string.empty)
                        {
                                messagebox.show( "非聊天室模式下必须先选择一个接收者! ",
                                                                "发送闪屏振动 ",
                                                                messageboxbuttons.ok,
                                                                messageboxicon.information);
                                return;
                        }
                        if   (private_rb.checked)
                        {
                                _nws.write(new   byte[]   {   0,   4   },   0,   2);
                                string   _receiver   =   online_cb.text;
                                _nws.write(encoding.unicode.getbytes(_receiver),   0,   encoding.unicode.getbytes(_receiver).length);
                                displaytxt   =   string.format( "[系统提示]您向   {0}   发送了一个闪屏振动。\r\n\r\n ",   _receiver);
                        }
                        else
                        {
                                _nws.write(new   byte[]   {   0,   3   },   0,   2);
                                displaytxt   =   "[系统提示]您向所有人发送了一个闪屏振动。\r\n\r\n ";
                        }
                        chatrcd_rtb.appendtext(displaytxt);
                        nudge();
                }

                ///   <summary>
                ///   以下是系统托盘菜单的处理函数
                ///   </summary>
                ///   <param   name= "sender "> </param>
                ///   <param   name= "e "> </param>
                private   void   close_tsmi_click(object   sender,   eventargs   e)
                {
                        close_btn_click(sender,   e);
                }
                private   void   notifyicon1_doubleclick(object   sender,   eventargs   e)
                {
                        comeback_tsmi_click(sender,   e);
                }
                private   void   comeback_tsmi_click(object   sender,   eventargs   e)
                {
                        notifyicon1.visible   =   false;
                        this.visible   =   true;
                        this.windowstate   =   formwindowstate.normal;
                        this.bringtofront();
                }

                #endregion
        }
}
发表于:2007-09-15 23:46:384楼 得分:0
学习中~
发表于:2007-09-17 15:54:525楼 得分:0
很棒,加油!
发表于:2007-09-30 01:37:226楼 得分:0


快速检索

最新资讯
热门点击