XuGang

记录一个程序员的成长

 

C#+flash socket 聊天程序(转)


很多人在研究flash的socket中经常会出现一些问题,所以提供一个别人的程序代码出来给大家参考...

这是VS2003下的c#程序的主要源代码,经过测试的。不包含一些自动生成的代码。
这些代码是根据一个开源的C# socket程序改编的,而且已经写了比较详细的注释了。

C#源代码
Windows 应用的窗体程序:Form1.cs

using System;
using System.IO;
using System.Drawing;
using System.Collections;//ArrayList引用到这个命名空间的类
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace ChatServer//服务器端命名空间
{
    
/// <summary>
    
/// Form1 的摘要说明。
    
/// </summary>

    public class Form1 : System.Windows.Forms.Form
    
{
        
private int listenport = 9050;//监听端口
        private TcpListener listener;//监听者
        private ArrayList clients;//所有的client
        private Thread processor;//处理线程
        private Socket clientsocket;//client套接字
        private Thread clientservice;//client的服务
        private System.Windows.Forms.ListBox lbClients;
        
private System.Windows.Forms.Label label1;//显示在线人员的List控件

        
private TcpClient tclient;

        
private NetworkStream ns;
        
private System.Windows.Forms.Button button1;

        
/// <summary>
        
/// 必需的设计器变量。
        
/// </summary>

        private System.ComponentModel.Container components = null;

        
public Form1()
        
{
            
//
            
// Windows 窗体设计器支持所必需的
            
//
            InitializeComponent();
            Thread.CurrentThread.IsBackground 
= true;
            
//
            
// TODO: 在 InitializeComponent 调用后添加任何构造函数代码
            
//
            clients = new ArrayList();//新建一个ArrayList类型用以存储所有的client
            processor = new Thread(new ThreadStart(StartListening));//新建一个处理线程
            processor.Start();//线程开始
            
//

        }



        
private void initClient()
        
{
            tclient 
= new TcpClient(Dns.GetHostName(),listenport);
            ns 
= tclient.GetStream();
            
            
//StreamReader sr = new StreamReader(ns); 

            
//ns.Write();
            
//MessageBox.Show("wwwwwwww");
        
            
//while()
            Thread cthread = new Thread(new ThreadStart(crun));
            cthread.Start();
            
        }

        
private void crun()
        
{
            
//MessageBox.Show("wwwwwwww");
            bool state = true;
            
//bool b = false;
            while(state)
            
{
                
//MessageBox.Show("wwwwwwww");
                string message;
                
//if(!b)
                
//{
                
//    message = "CONN|host";
                
//    b = !b;
                
//}
                
//else
                message = "CHAT|test";
                
byte[] bf = System.Text.Encoding.UTF8.GetBytes(message.ToCharArray());
                ns.Write(bf, 
0, bf.Length);
                Thread.Sleep(
2000);
            }


        }



        
/// <summary>
        
/// 清理所有正在使用的资源。
        
/// </summary>

        protected override void Dispose( bool disposing )
        
{

        
                
int c = clients.Count;
                
for(int n=0; n<c; n++)
                
{
                    Client cl 
= (Client)clients[n];
                    cl.Sock.Close();
                    cl.CLThread.Abort();
                }

            


            
//client.Close();
            listener.Stop();
            processor.Abort();
            
if( disposing )
            
{
                
if (components != null
                
{
                    components.Dispose();
                }

            }

            
base.Dispose( disposing );
        }


        
Windows Form Designer generated code

        
/// <summary>
        
/// 开始监听
        
/// </summary>

        private void StartListening()
        
{

            IPAddress ipAddress 
= Dns.Resolve(Dns.GetHostName()).AddressList[0];
            
//IPAddress ipAddress = IPAddress.Parse("192.168.0.132");

            
            label1.Text
=ipAddress.ToString();
            IPEndPoint ipLocalEndPoint 
= new IPEndPoint(ipAddress, listenport);

            listener 
= new TcpListener(ipLocalEndPoint);
            listener.Start();
            
while (true
            
{
                
try
                
{
                    Socket s 
= listener.AcceptSocket();//接收一个套接字
                    clientsocket = s;//赋值给clientsocket
                    clientservice = new Thread(new ThreadStart(ServiceClient));//为新进client服务建立线程
                    clientservice.Start();//线程开始
                }

                
catch(Exception e)//如果出现异常则打控制台打印到屏幕
                {
                    Console.WriteLine(e.ToString() );
                }

            }

        }


        
/// <summary>
        
/// 给一个客户提供服务
        
/// </summary>

        private void ServiceClient()
        
{
            Socket client 
= clientsocket;//赋值给client
            bool keepalive = true;
            
bool s;
            
while (keepalive)
            
{

                Byte[] buffer 
= new Byte[1024];//一个1024bits的缓存区
                try
                
{
                    client.Receive(buffer);
                }
 
                
catch(SocketException ex) 
                

                    
//客户端退出     
                    
//MessageBox.Show(ex.ToString());
                    string leaveName="";
                    
int remove = 0;
                    
bool found = false;
                    
int c = clients.Count;
                    
//从client的ArrayList中查找有没有相符的client
                    
//有的话就作好删掉的准备
                    for(int n=0; n<c; n++)
                    
{
                        Client cl 
= (Client)clients[n];
                        
if(cl.Host==client.RemoteEndPoint)
                        
{
                            leaveName 
= cl.Name;
                            remove 
= n;
                            found 
= true;
                            lbClients.Items.Remove(cl);
//List控件中删除这个client
                            break;
                        }

                    }


                    
if(found)
                    
{
                        
for(int n=0; n<c; n++)
                        
{
                            Client cl 
= (Client)clients[n];
                            
//MessageBox.Show( "GONE|"+leaveName);
                            SendToClient(cl, "GONE|"+leaveName);
                        }

                    
                        clients.RemoveAt(remove);
//从clients的ArrayList里面删掉要当前要退出的client
                        client.Close();//关闭套接口
                        keepalive = false;//keepalive=false则这个线程服务完毕
                    }


                }




                
string clientcommand = System.Text.Encoding.UTF8.GetString(buffer);//把得到的数据用ASCII的编码形式读出解决中文的显示问题

                label1.Text
=clientcommand;

                
string[] tokens = clientcommand.Split(new Char[]{'|'});//以|号划分的命令数据
                Console.WriteLine(clientcommand);

                
if (tokens[0== "CONN")//连接命令消息
                {
                    
//给现有的client发送新进一个client的消息
                    for(int n=0; n<clients.Count; n++
                    
{
                        Client cl 
= (Client)clients[n];
                        SendToClient(cl, 
"JOIN|" + tokens[1]);
                    }

                    
                    
//新加一个client
                    EndPoint ep = client.RemoteEndPoint;
                    Client c 
= new Client(tokens[1], ep, clientservice, client);
                    clients.Add(c);
                    
                    
//给每个client发一个当前所有client的列表消息
                    
//string message = "LIST|" + GetChatterList();

                    
//new byte(0)
                    
//byte b = 0;

                    
string message = "LIST|"+"asdasd";
                    
//MessageBox.Show(message.Length +"="+message);
                    SendToClient(c, message);

                    
//MessageBox.Show(message);

                    
//服务器List控件新加这个client
                    lbClients.Items.Add(c);
                    
                }

                
else
                    
if (tokens[0== "CHAT")//聊天命令消息
                {
                    
//给每个client发送聊天消息
                    for(int n=0; n<clients.Count; n++)
                    
{
                        Client cl 
= (Client)clients[n];
                        SendToClient(cl, clientcommand);
                    }

                }

                
else
                    
if (tokens[0== "PRIV"//私聊命令消息
                {
                    
                    
string destclient = tokens[2];//目标client
                    for(int n=0; n<clients.Count; n++
                    
{
                        Client cl 
= (Client)clients[n];
                        
if(cl.Name.CompareTo(tokens[2]) == 0)//给目标client发聊天消息
                            SendToClient(cl, clientcommand);
                        
if(cl.Name.CompareTo(tokens[1]) == 0)//给自己发聊天消息
                            SendToClient(cl, clientcommand);
                    }

                }

                
else
                    
if (tokens[0== "GONE")//离开命令消息
                {
                    
int remove = 0;
                    
bool found = false;
                    
int c = clients.Count;
                    
//从client的ArrayList中查找有没有相符的client
                    
//有的话就作好删掉的准备
                    for(int n=0; n<c; n++)
                    
{
                        Client cl 
= (Client)clients[n];
                        SendToClient(cl, clientcommand);
                        
if(cl.Name.CompareTo(tokens[1]) == 0)
                        
{
                            remove 
= n;
                            found 
= true;
                            lbClients.Items.Remove(cl);
//List控件中删除这个client
                        }

                    }

                    
if(found)
                        clients.RemoveAt(remove);
//从clients的ArrayList里面删掉要当前要退出的client
                    client.Close();//关闭套接口
                    keepalive = false;//keepalive=false则这个线程服务完毕
                }

                
else
                
{
                    
//MessageBox.Show(clientcommand);
                    for(int n=0; n<clients.Count; n++)
                    
{
                        Client cl 
= (Client)clients[n];
                        SendToClient(cl, 
"-");
                    }

                }

            }
 
        

        }


        
/// <summary>
        
/// 发送消息到指定的client
        
/// </summary>
        
/// <param name="cl">client</param>
        
/// <param name="message">消息</param>

        private void SendToClient(Client cl, string message)
        
{
            
try
            
{
                
//MessageBox.Show(message);
                message += "0";
                
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(message.ToCharArray());
                buffer[buffer.Length 
-2= 0;
                cl.Sock.Send(buffer,buffer.Length,
0);
            }

            
catch(Exception)//如果有异常则退出
            {
                
//MessageBox.Show(message);
                clients.Remove(cl);
                lbClients.Items.Remove(cl.Name 
+ " : " + cl.Host.ToString());
                
for(int n=0; n<clients.Count; n++)
                
{
                    Client cl1 
= (Client)clients[n];
                    SendToClient(cl1, 
"GONE|"+cl.Name);
                }

                cl.Sock.Close();
                cl.CLThread.Abort();
                
            }

        }


        
/// <summary>
        
/// 获得所有聊天者的列表
        
/// 中间以"|"符号间隔
        
/// </summary>
        
/// <returns></returns>

        private string GetChatterList()
        
{
            
string chatters = "";
            
for(int n=0; n<clients.Count; n++)
            
{
                Client cl 
= (Client)clients[n];
                chatters 
+= cl.Name;
                
//MessageBox.Show(cl.Name.Length +"=" +cl.Name);
                
//chatters += "welcome";
                chatters += "|";
                
//MessageBox.Show(cl.Name);
                
            }

            
//chatters += "欢迎你的到来";
            
//MessageBox.Show(chatters);
            chatters.Trim(new char[]{'|'});
        
            
return chatters;

            
        }


        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main() 
        
{
            Application.Run(
new Form1());
        }


        
private void Form1_Load(object sender, System.EventArgs e)
        
{
        
        }


        
private void lbClients_SelectedIndexChanged(object sender, System.EventArgs e)
        
{
        
        }


        
private void button1_Click(object sender, System.EventArgs e)
        
{
            
//initClient();
            if(clients.Count > 0)
            
{
                
int c = clients.Count;
                
for(int n=0; n<c; n++)
                
{
                    
string message = "CHAT|..";
            
                    Client cl 
= (Client)clients[n];
                    SendToClient(cl, message);
                }


            }

        }


    }

}


Class 类程序:Client.cs

using System;
using System.Threading;

namespace ChatServer //定义命名空间
{
    
using System.Net.Sockets;
    
using System.Net;

    
/// <summary>
    
/// Client 的摘要说明。
    
/// </summary>

    public class Client
    
{
        
private Thread clthread;//client的线程
        private EndPoint endpoint;//终端
        private string name;//client的名称
        private Socket sock;//套接口

        
/// <summary>
        
/// 构造函数,初始化所有的私有变量
        
/// </summary>
        
/// <param name="_name">名称</param>
        
/// <param name="_endpoint">终端</param>
        
/// <param name="_thread">线程</param>
        
/// <param name="_sock">套接口</param>

        public Client(string _name, EndPoint _endpoint, Thread _thread, Socket _sock)
        
{
            
// TODO: 在此处添加构造函数逻辑
            clthread = _thread;
            endpoint 
= _endpoint;
            name 
= _name;
            sock 
= _sock;
        }


        
/// <summary>
        
/// 重载:转成字串
        
/// </summary>
        
/// <returns>返回终端加上client名称</returns>

        public override string ToString()
        
{
            
return endpoint.ToString()+ " : " + name;
        }


        
/// <summary>
        
/// 获取和设置线程
        
/// </summary>

        public Thread CLThread
        
{
            
get{return clthread;}
            
set{clthread = value;}
        }


        
/// <summary>
        
/// 获取和设置终端
        
/// </summary>

        public EndPoint Host
        
{
            
get{return endpoint;}
            
set{endpoint = value;}
        }


        
/// <summary>
        
/// 获取和设置client名称
        
/// </summary>

        public string Name
        
{
            
get{return name;}
            
set{name = value;}
        }


        
/// <summary>
        
/// 获取和设置套接口
        
/// </summary>

        public Socket Sock
        
{
            
get{return sock;}
            
set{sock = value;}
        }

    }

}


flash源代码
这是flash的代码,代码比较简单,没有写什么注释。
聊天.fla

function OnConnect(success) {
 
if (success) {
  trace(
"Connection succeeded!");
  isConn 
= true;
  socket.send(
"CONN|"+userNameIt.text);
  userList.addItem('所有人');
 }
 else {
  trace(
"Connection failed!");
 }

}

function OnData(src) {
 
// 此处是您的语句
 trace(src)
 strArray 
= src.split('|');
 
 temp 
= strArray[0];
 trace(strArray.length
+'\t'+strArray);
 
if (temp == 'LIST') {
  userList.removeAll();
  
for (i=1; i<strArray.length; i++{
   userList.addItem(strArray[i]);
  }

 }
 else if (temp == 'JOIN') {
  userList.addItem(strArray[
1]);
  smgText.text 
+= strArray[1+ '进来了···'+'\n';
 }
 else if (temp == 'CHAT') {
  smgText.text 
+= strArray[1]+'\n';
 }
 else if (temp == 'PRIV') {
  smgText.text 
+= strArray[strArray.length-1]+'\n';
  
break;
 }
 else if (temp == 'GONE') {
  
for (var i = 0; i<userList.length; i++{
   
if (userList.getItemAt(i).label == strArray[1]) {
    smgText.text 
+= userList.getItemAt(i).label + '离开了···'+'\n';
    userList.removeItemAt(i);
   }

  }

 }
 else if (strArray[1== 'CHAT') {
  smgText.text 
+= strArray[2]+'\n';
 }

 temp 
= "";
 smgText.vPosition 
= smgText.maxVPosition;
}


connectBtn.onRelease 
= function() {
 socket 
= new XMLSocket();
 socket.onConnect 
= OnConnect;
 socket.onData 
= OnData;
 
//
 if (!socket.connect("192.168.0.132"9050)) {
  trace(
"Connection failed!");
 }

}
;
/////////////////////////////////////////
sendMsgBtn.onRelease = function() {
 
if (msgIt.text != '') {
  
if (userList.selectedItem == undefined || userList.selectedItem.label == '所有人' || userList.selectedItem.label == userNameIt.text) {
   socket.send(
"CHAT|"+userNameIt.text+' 说:'+msgIt.text);
  }
 else if (!privateCheckBox.selected) {
   socket.send(
"CHAT|"+userNameIt.text+' 对 '+userList.selectedItem.label+' 说:'+msgIt.text);
  }
 else {
   socket.send(
"PRIV|"+userNameIt.text+'|'+userList.selectedItem.label+'|'+userNameIt.text+' 悄悄的对 '+userList.selectedItem.label+' 说:'+msgIt.text);
  }

 }

 msgIt.text 
= '';
}
;
disconnectBtn.onRelease 
= function() {
 isConn 
= false;
 socket.send(
"GONE|"+userNameIt.text);
 socket.close();
}
;
function init() {

 connected
=false;
 
 smgText.text 
= '';
 temp 
= '';
}

init();
//连接到服务器
var isConn:Boolean = false;

myListener 
= new Object();
myListener.onKeyDown 
= function () {
if(Key.getCode() == 13)
sendMsgBtn.onRelease();
}


Key.addListener(myListener);


来源:
http://www.roading.net/blog/article.asp?id=78
http://www.roading.net/blog/post_79.html

posted on 2007-12-04 11:41  钢钢  阅读(1709)  评论(0编辑  收藏  举报

导航