快捷搜索:  xxx  as  推理研究所  幼幼  侦探研究所

万博娱乐manbext客户端:以异步的方式操作TCPIP套接字——以异步方式实现简单的聊天室



通俗的TCP/IP开拓要领大年夜家都应该异常纯熟,但在系统开拓的时刻每每会碰到问题。

比如:在开拓一个简单的谈天室的时刻,一样平常环境下,Windows利用法度榜样会处于同步要领运行,当监听的客户端越多,办事器的负荷将会越重,信息发送与接管都邑受到影响。这时刻,我们就应该考试测验应用异步的TCP/IP通讯来缓解办事器的压力。

下面以一个最简单的谈天室办事器真个例子来阐明异步TCP/IP的威力,先开拓一个ChatClient类作为客户治理的代理类,每当办事器接管到信息时,就会把信息处置惩罚并发送给每一个在线客户。

void Main()

{

IPAddress ipAddress = IPAddress.Parse("127.0.0.1" );//默认地址

TcpListener tcpListener = new TcpListener(ipAddress,500 );

tcpListener.Start();

while (isListen)//以一个逝世轮回来实现监听

{

ChatClient chatClient = new ChatClient(tcpListener.AcceptTcpClient());//调用一个ChatClient工具来实现监听

}

tcpListener.Stop();

}

ChatClient中存在着一个Hashtabel类的静态变量 clients,此变量用来存贮在线的客户端信息,每当对一个客户端进行监听时,系统就天生一个ChatClient工具,然后在变量clients中加入此客户真个信息。在接管客户端信息时,信息会调用Receive(IAsyncResult async)措施,把接管到的信息发送给每一个在线客户。

值得留意的是,每当接管到客户信息时,系统都邑使用Stream.BeginRead()的措施去接管信息,然后把信息发送到每一个在线客户,这样做就可以使用异步的要领把信息进行接管,从而令主线程赶早获得开释,前进系统的机能。

public class ChatClient

{

private TcpClient _tcpClient;

private byte [] byteMessage;

private string _clientEndPoint;

public volatile string message;

public static Hashtable clients= new Hashtable();//以此静态变量存处多个客户端地址

public ChatClient(TcpClient tcpClient)

{

_tcpClient = tcpClient;

_clientEndPoint = _tcpClient.Client.RemoteEndPoint.ToString();

Console.WrtieLine("连接成功,客户端EndPoint为"+_clientEndPoint);

ChatClient.clients.Add(_clientEndPoint, this );//每创建一个工具,就会将客户真个ChatClient工万博娱乐manbext客户端具存入clients;

byteMessage=new byte [_tcpClient.ReceiveBufferSize];

lock (_tcpClient.GetStream())//接管信息,应用lock避免数据冲突

{

_tcpClie万博娱乐manbext客户端nt.GetStream().BeginRead(byteMessage, 0, _tcpClient.ReceiveBufferSize, new AsyncCallback(Receive), null);

//就在此处应用异步的IO线程进行数据读取,这样每个一客户真个都处于一个IO线程中处置惩罚,使主线程赶早获得开释

//这样做就缓解了办事器端压力。

}

}

public void Receive(IAsyncResult iAsyncResult)

{

try

{

int length;

lock (_tcpClient.GetStream())//信息接管,应用lock避免数据冲突

{

length= _tcpClient.GetStream().EndRead(iAsyncResult);

}

if (length)

{

MessageBox.Show(_tcpClient.Client.RemoteEndPoint + "已经断线" );

clients.Remove(_tcpClient);

return ;

}

message=Encoding.Unicode.GetString(byteMessage,0 ,length);

SendToEveryone(message);

//在此时我们可以在此处调用SendToEveryone措施,使用clients变量以Stream.Write措施为每个客户端发送信息。

lock (_tcp万博娱乐manbext客户端Client.GetStream())//再次监听,应用lock避免数据冲突

{

_tcpClient.GetStream().BeginRead(byteMessage, 0, _tcpClient.ReceiveBufferSize, new AsyncCallback(Receive), null );

//再次调用Stream.BeginRead措施,以监听以下次客户的信息

}

}

catch (Exception ex)

{

clients.Remove(_tcpClient);

_tcpClient.GetStream().Close();

_tcpClient.Close();

}

}

//经由过程Send措施把信息转换成二进制数据,然后发送到客户端

public void Send(string message)

{

try

{

NetworkStream ns;

lock (_tcpClient.GetStream())

{

ns = _tcpClient.GetStream();

}

byte万博娱乐manbext客户端[] byteMessage = Encoding.ASCII.GetBytes(message);

ns.Write(byteMessage, 0, byteMessage.Length);

ns.Flush();

}

catch (Exception ex)

{

MessageBox.Show(ex.Message);

}

}

//因为客户端信息记录在HashTabel变量clients中,当信息接管后,就会经由过程此变量把信息发送给每一个在线客户。

public void SendToEveryone(string message)

{

foreach (DictionaryEntry client in clients)

{

ChatClient chatClient = (ChatClient)client.Value;

chatClient.Send(message);

}

}

}

测试结果:

至于窗口的设计和客户真个设计在这里就省略不说,这里的目的只是要你懂得办事器端多线程TCP/IP信息接管的道理。

这个例子里,ChatClient类应用异步的IO线程进行数据读取,这样每个一客户真个都处于一个IO线程中处置惩罚,使主线程赶早获得开释,这样做就缓解了办事器端压力。

这时万博娱乐manbext客户端刻你可以做一个测试,此谈天室在默认环境下可吸收大年夜约3000个客户端连接,仍旧能够正常事情。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: