您的位置:首页 > 编程语言 > C#

我的 C#+flash socket 聊天程序(C#源代码)

2008-02-18 18:02 459 查看
此篇文章为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
;
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
;
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
;
//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
;
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
;
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
;
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
;
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
;
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
;
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
;
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
;
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;}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: