首页 > 开发 > 综合 > 正文

简单的多人聊天(C#.Socket).

2024-07-21 02:17:49
字体:
来源:转载
供稿:网友
 

/********************************8chatserver:*************************************************/

using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;

using system.threading;
using system.net.sockets;
using system.net;
namespace chat_server
{
 /// <summary>
 /// form1 的摘要说明。
 /// </summary>
 public class form1 : system.windows.forms.form
 {
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private system.componentmodel.container components = null;

  static int listenport=6666;
  socket clientsocket;
  private system.windows.forms.listbox lbclients;
  arraylist clients;
  private system.windows.forms.button button1;
  thread clientservice;
  private system.windows.forms.label label1;
  thread threadlisten;

  public form1()
  {
   
   initializecomponent();

  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void dispose( bool disposing )
  {
   if( disposing )
   {
    
    if(clientservice != null)
    {
     clientservice.abort();
    }
    if(threadlisten != null)
    {
     try
     {
      threadlisten.abort();
     }
     catch(exception ex)
     {
      threadlisten = null;
     }
    }    

    if (components != null)
    {
     components.dispose();
    }
   }
   base.dispose( disposing );
   
  }

  #region windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void initializecomponent()
  {
   this.lbclients = new system.windows.forms.listbox();
   this.button1 = new system.windows.forms.button();
   this.label1 = new system.windows.forms.label();
   this.suspendlayout();
   //
   // lbclients
   //
   this.lbclients.itemheight = 12;
   this.lbclients.location = new system.drawing.point(16, 24);
   this.lbclients.name = "lbclients";
   this.lbclients.size = new system.drawing.size(184, 268);
   this.lbclients.tabindex = 0;
   //
   // button1
   //
   this.button1.location = new system.drawing.point(272, 56);
   this.button1.name = "button1";
   this.button1.tabindex = 1;
   this.button1.text = "button1";
   this.button1.click += new system.eventhandler(this.button1_click);
   //
   // label1
   //
   this.label1.location = new system.drawing.point(240, 136);
   this.label1.name = "label1";
   this.label1.size = new system.drawing.size(120, 32);
   this.label1.tabindex = 2;
   this.label1.text = "label1";
   //
   // form1
   //
   this.autoscalebasesize = new system.drawing.size(6, 14);
   this.clientsize = new system.drawing.size(368, 309);
   this.controls.add(this.label1);
   this.controls.add(this.button1);
   this.controls.add(this.lbclients);
   this.name = "form1";
   this.text = "form1";
   this.load += new system.eventhandler(this.form1_load);
   this.resumelayout(false);

  }
  #endregion

  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [stathread]
  static void main()
  {
   application.run(new form1());
  }

  private void startlistening()
  {
    tcplistener listener = new tcplistener(listenport);
    listener.start();
   label1.text = "listening....";
   while (true)
   {
    try
    {
    
     socket s = listener.acceptsocket();
     clientsocket = s;
     clientservice = new thread(new threadstart(serviceclient));
     clientservice.start();
    }
    catch(exception ex)
    {
     messagebox.show("listening error: "+ex.message);
    }
   }   
  }
  private void serviceclient()
  {
   socket client = clientsocket;
   bool keepalive = true;


   while (keepalive)
   {
    byte[] buffer = new byte[1024];
    int buflen = 0;
    try
    {
     buflen = client.available ;
     
     client.receive(buffer,0,buflen,socketflags.none);
     if(buflen==0)
      continue;    
    }
    catch(exception ex)
    {
     messagebox.show("receive error:"+ex.message);
     return;
    }
    
    string clientcommand = system.text.encoding.ascii.getstring(buffer).substring(0,buflen);

    string[] tokens = clientcommand.split(new char[]{'|'});
    console.writeline(clientcommand);

    if (tokens[0] == "conn")
    {
     for(int n=0; n<clients.count;n++)
     {
      client cl = (client)clients[n];
      sendtoclient(cl, "join|" + tokens[1]);
     }
     endpoint ep = client.remoteendpoint;
     client c = new client(tokens[1], ep, clientservice, client);
     
     string message = "list|" + getchatterlist() +"/r/n";
     sendtoclient(c, message);

     clients.add(c);


     lbclients.items.add(c);


    }
    if (tokens[0] == "chat")
    {
     for(int n=0; n<clients.count;n++)
     {
      client cl = (client)clients[n];
      sendtoclient(cl, clientcommand);
     }
    }
    if (tokens[0] == "priv")
    {
     string destclient = tokens[3];
     for(int n=0; n<clients.count;n++)
     {
      client cl = (client)clients[n];
      if(cl.name.compareto(tokens[3]) == 0)
       sendtoclient(cl, clientcommand);
      if(cl.name.compareto(tokens[1]) == 0)
       sendtoclient(cl, clientcommand);
     }
    }
    if (tokens[0] == "gone")
    {
     int remove = 0;
     bool found = false;
     int c = clients.count;
     for(int n=0; n<clients.count;n++)
     {
      client cl = (client)clients[n];
      sendtoclient(cl, clientcommand);
      if(cl.name.compareto(tokens[1]) == 0)
      {
       remove = n;
       found = true;
       lbclients.items.remove(cl);
      }
     }
     if(found)
      clients.removeat(remove);
     client.close();
     keepalive = false;
    }
   }
  }

  private string getchatterlist()
  {
   string result = "";

   for(int i=0;i<clients.count;i++)
   {
    result += ((client)clients[i]).name+"|";
   }
   return result;

  }

  private void sendtoclient(client cl,string clientcommand)
  {
   byte[] message = system.text.encoding.ascii.getbytes(clientcommand);
   socket s = cl.sock;
   if(s.connected)
   {
    s.send(message,message.length,0);
   }
  }

  private void form1_load(object sender, system.eventargs e)
  {
   clients = new arraylist();
  }

  private void button1_click(object sender, system.eventargs e)
  {
   threadlisten = new thread(new threadstart(startlistening));
   threadlisten.start();  
  }
 }
}


/***************************** client类 ********************/

/************************** 放于 chatserver 项目中 *********/

using system;
using system.threading;

namespace chat_server
{
 using system.net.sockets;
 using system.net;

 ///
 /// client 的摘要说明。
 ///
 public class client
 {
  private thread clthread;
  private endpoint endpoint;
  private string name;
  private socket sock;

  public client(string _name, endpoint _endpoint, thread _thread, socket _sock)
  {
   // todo: 在此处添加构造函数逻辑
   clthread = _thread;
   endpoint = _endpoint;
   name = _name;
   sock = _sock;
  }

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

  public thread clthread
  {
   get{return clthread;}
   set{clthread = value;}
  }

  public endpoint host
  {
   get{return endpoint;}
   set{endpoint = value;}
  }

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

  public socket sock
  {
   get{return sock;}
   set{sock = value;}
  }
 }
}

/***************************** chatclient ************************************/

using system;
using system.drawing;
using system.collections;
using system.componentmodel;
using system.windows.forms;
using system.data;

using system.io;
using system.net;
using system.net.sockets;
using system.threading;

namespace chat_client
{
 /// <summary>
 /// form1 的摘要说明。
 /// </summary>
 public class form1 : system.windows.forms.form
 {
  private system.windows.forms.checkbox checkbox1;
  private system.windows.forms.statusbar statusbar1;

  networkstream ns;
  streamreader sr;
  tcpclient clientsocket;
  bool connected;
  thread receive;
  string serveraddress = "219.228.231.85";
  int serverport = 6666;

  private system.windows.forms.richtextbox rtbchatin;
  private system.windows.forms.listbox lbchatters;
  private system.windows.forms.textbox chatout;
  private system.windows.forms.button btndisconnect;
  private system.windows.forms.button btnsend;
  private system.windows.forms.textbox clientname;

  string clientname;
  private system.windows.forms.button btnconnect;

  private system.componentmodel.container components = null;

  public form1()
  {
   
   initializecomponent();

  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void dispose( bool disposing )
  {
   if( disposing )
   {
    if(receive != null)
    {
     quitchat();
    }
    if (components != null)
    {
     components.dispose();
    }
   }
   base.dispose( disposing );
  }

  #region windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void initializecomponent()
  {
   this.lbchatters = new system.windows.forms.listbox();
   this.rtbchatin = new system.windows.forms.richtextbox();
   this.checkbox1 = new system.windows.forms.checkbox();
   this.chatout = new system.windows.forms.textbox();
   this.btnsend = new system.windows.forms.button();
   this.statusbar1 = new system.windows.forms.statusbar();
   this.btndisconnect = new system.windows.forms.button();
   this.clientname = new system.windows.forms.textbox();
   this.btnconnect = new system.windows.forms.button();
   this.suspendlayout();
   //
   // lbchatters
   //
   this.lbchatters.itemheight = 12;
   this.lbchatters.location = new system.drawing.point(32, 40);
   this.lbchatters.name = "lbchatters";
   this.lbchatters.size = new system.drawing.size(112, 172);
   this.lbchatters.tabindex = 0;
   //
   // rtbchatin
   //
   this.rtbchatin.location = new system.drawing.point(160, 40);
   this.rtbchatin.name = "rtbchatin";
   this.rtbchatin.size = new system.drawing.size(208, 176);
   this.rtbchatin.tabindex = 2;
   this.rtbchatin.text = "";
   //
   // checkbox1
   //
   this.checkbox1.location = new system.drawing.point(16, 248);
   this.checkbox1.name = "checkbox1";
   this.checkbox1.tabindex = 3;
   this.checkbox1.text = "checkbox1";
   //
   // chatout
   //
   this.chatout.location = new system.drawing.point(136, 248);
   this.chatout.name = "chatout";
   this.chatout.size = new system.drawing.size(136, 21);
   this.chatout.tabindex = 4;
   this.chatout.text = "message";
   //
   // btnsend
   //
   this.btnsend.location = new system.drawing.point(336, 248);
   this.btnsend.name = "btnsend";
   this.btnsend.tabindex = 5;
   this.btnsend.text = "send";
   this.btnsend.click += new system.eventhandler(this.btnsend_click);
   //
   // statusbar1
   //
   this.statusbar1.location = new system.drawing.point(0, 287);
   this.statusbar1.name = "statusbar1";
   this.statusbar1.size = new system.drawing.size(464, 22);
   this.statusbar1.tabindex = 6;
   this.statusbar1.text = "statusbar1";
   //
   // btndisconnect
   //
   this.btndisconnect.enabled = false;
   this.btndisconnect.location = new system.drawing.point(392, 112);
   this.btndisconnect.name = "btndisconnect";
   this.btndisconnect.size = new system.drawing.size(64, 32);
   this.btndisconnect.tabindex = 7;
   this.btndisconnect.text = "断开";
   this.btndisconnect.click += new system.eventhandler(this.btndisconnect_click);
   //
   // clientname
   //
   this.clientname.location = new system.drawing.point(96, 8);
   this.clientname.name = "clientname";
   this.clientname.tabindex = 8;
   this.clientname.text = "name";
   //
   // btnconnect
   //
   this.btnconnect.location = new system.drawing.point(392, 56);
   this.btnconnect.name = "btnconnect";
   this.btnconnect.size = new system.drawing.size(64, 32);
   this.btnconnect.tabindex = 9;
   this.btnconnect.text = "连接";
   this.btnconnect.click += new system.eventhandler(this.btnconnect_click);
   //
   // form1
   //
   this.autoscalebasesize = new system.drawing.size(6, 14);
   this.clientsize = new system.drawing.size(464, 309);
   this.controls.add(this.btnconnect);
   this.controls.add(this.clientname);
   this.controls.add(this.btndisconnect);
   this.controls.add(this.statusbar1);
   this.controls.add(this.btnsend);
   this.controls.add(this.chatout);
   this.controls.add(this.checkbox1);
   this.controls.add(this.rtbchatin);
   this.controls.add(this.lbchatters);
   this.name = "form1";
   this.text = "form1";
   this.resumelayout(false);

  }
  #endregion

  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [stathread]
  static void main()
  {
   application.run(new form1());
  }

  private void establishconnection()
  {
   statusbar1.text = "正在连接到服务器";
   
   try
   {
    clientsocket = new tcpclient(serveraddress,serverport);
    ns = clientsocket.getstream();
    sr = new streamreader(ns);
    connected = true;
   
   }
   catch (exception)
   {
    messagebox.show("不能连接到服务器!","错误",
     messageboxbuttons.ok, messageboxicon.exclamation);
    statusbar1.text = "已断开连接";
   }
  }

  private void registerwithserver()
  {
   lbchatters.items.clear();

   clientname = clientname.text;
   try
   {
    string command = "conn|" + clientname; //+"/r/n";
    byte[] outbytes = system.text.encoding.ascii.getbytes(command.tochararray());
    ns.write(outbytes,0,outbytes.length);


    string serverresponse = sr.readline();
    serverresponse.trim();
    string[] tokens = serverresponse.split('|');
    if(tokens[0] == "list")
    {
     statusbar1.text = "已连接";
     btndisconnect.enabled = true;
    }
    if(tokens[1] != "")
    {
     for(int n=1; n<tokens.length;n++)
      lbchatters.items.add(tokens[n].trim(new char[]{'/r','/n'}));
    }
    this.text = clientname + ":已连接到服务器";    

   }
   catch (exception ex)
   {
    messagebox.show("注册时发生错误!"+ex.message,"错误",
     messageboxbuttons.ok, messageboxicon.exclamation);
    connected = false;
   }
  }

  private void receivechat()
  {
   bool keepalive = true;
   while (keepalive)
   {
    try
    {
     byte[] buffer = new byte[1024];  // 2048???
     ns.read(buffer,0,buffer.length);
     string chatter = system.text.encoding.ascii.getstring(buffer);
     string[] tokens = chatter.split(new char[]{'|'});

     if (tokens[0] == "chat")
     {
      rtbchatin.appendtext(tokens[1]);
//      if(logging)
//       logwriter.writeline(tokens[1]);
     }
     if (tokens[0] == "priv")
     {
      rtbchatin.appendtext("private from ");
      rtbchatin.appendtext(tokens[1].trim() );
      rtbchatin.appendtext(tokens[2] + "/r/n");
//      if(logging)
//      {
//       logwriter.write("private from ");
//       logwriter.write(tokens[1].trim() );
//       logwriter.writeline(tokens[2] + "/r/n");
//      }
     }
     if (tokens[0] == "join")
     {
      rtbchatin.appendtext(tokens[1].trim() );
      rtbchatin.appendtext(" has joined the chat/r/n");
//      if(logging)
//      {
//       logwriter.writeline(tokens[1]+" has joined the chat");
//      }
      string newguy = tokens[1].trim(new char[]{'/r','/n'});
      lbchatters.items.add(newguy);
     }
     if (tokens[0] == "gone")
     {
      rtbchatin.appendtext(tokens[1].trim() );
      rtbchatin.appendtext(" has left the chat/r/n");
//      if(logging)
//      {
//       logwriter.writeline(tokens[1]+" has left the chat");
//      }
      lbchatters.items.remove(tokens[1].trim(new char[]{'/r','/n'}));
     }
     if (tokens[0] == "quit")
     {
      ns.close();
      clientsocket.close();
      keepalive = false;
      statusbar1.text = "服务器端已停止";
      connected= false;
      btnsend.enabled = false;
      btndisconnect.enabled = false;
     }
    }
    catch(exception){}
   }
  }

  private void quitchat()
  {
   if(connected)
   {
    try
    {
     string command = "gone|" + clientname;
     byte[] outbytes = system.text.encoding.ascii.getbytes(command.tochararray());
     ns.write(outbytes,0,outbytes.length);
     clientsocket.close();
    }
    catch(exception ex)
    {
     messagebox.show(ex.message);
    }
   }
//   if(logging)
//    logwriter.close();
   if(receive != null && receive.isalive)
    receive.abort();
   this.text = "客户端";
   
   connected = false;

  }

  private void btnsend_click(object sender, system.eventargs e)
  {
   if(connected)
   {
    try
    {
     string command = "chat|" + clientname+": "+chatout.text+"/r/n";
     byte[] outbytes = system.text.encoding.ascii.getbytes(command.tochararray());
     ns.write(outbytes,0,outbytes.length);
     //clientsocket.close();
    }
    catch(exception ex)
    {
     messagebox.show(ex.message);
    }
   }
  }

  private void btnconnect_click(object sender, system.eventargs e)
  {
   establishconnection();
   registerwithserver();
   if(connected)
   {   
    receive = new thread(new threadstart(receivechat));
    receive.start();
   }
  }

  private void btndisconnect_click(object sender, system.eventargs e)
  {
   quitchat();
  }
 }
}


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表