正文

我的 C#+flash socket 聊天程序(C#源代码)2007-06-11 11:39:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/Csharpsky/26655.html

分享到:

此篇文章为roading所有,欢迎转载,但请注明原处.

看见还有很多人在研究flash的socket,其中经常会出现一些问题,所以将我以前写的一个程序代码拿出来给大家参考...

这是c#的代码,经过测试的,本来想把源程序都放上来,可以我用的是vs2005(而且现在又坏了,系统出问题了),下面是程序的主要源代码,不包含一些自动生成的代码.这些代码是根据一个开源的C#socket程序改编的,而且我已经写了比较详细的注释了,如果你看了这些代码还是发现有问题,可以向我索取完整的源程序:

把源文件传上来,大家可以下载(gmail又打不开了,不能给留email的同学发了,自己下载吧):

 点击下载此文件
//--------------------------------

//---------------------------------------------------------------------------------------------------------------
//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();//线程开始
   //

  }


  /// <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 );
  }


  /// <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 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);
    }

   }
  }

 

 }
}

//--------------------------------------------------------------------------------------------------------------

//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;}
  }
 }
}

阅读(5739) | 评论(1)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册