C# socket服务端一些并发问题
本帖最后由 caozhy 于 2014-03-12 09:08:28 编辑
很简单 也很常用的代码 如下.
//启动
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(new IPEndPoint(IPAddress.Any, int.Parse(textBox1.Text)));
socket.Listen(1000);
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
//连接
public void ClientAccepted(IAsyncResult ar)
{
var socket = ar.AsyncState as Socket;
var client = socket.EndAccept(ar);
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
}
//接收数据
public void ReceiveMessage(IAsyncResult ar)
{
var socket = ar.AsyncState as Socket;
var length = socket.EndReceive(ar);
if (length==0)
return;
byte[] reallData = new byte[length];
Array.Copy(buffer, reallData, length);
//do something
}
问题 就是在接收数据里面 我用测试软件 已经可以建立超过2W个长连接.保存也没什么问题(就是内存大了点)
但是 2W个client并发的时候 也就是发送数据 程序就立马关掉 就算在VS调试的时候 也一样
如果是1000就没问题.
关闭了 没任何错误 就连windows日志都没有....这样的问题 如何解决.
------解决方案--------------------//可以加并发控制信号量,参考
private Semaphore semaphoreAcceptedClients;
//启动
this.semaphoreAcceptedClients = new Semaphore(1000, 1000);
//连接
this.semaphoreAcceptedClients.WaitOne();
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
------解决方案--------------------socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);改成
new AsyncCallback(ar =>{
var socket = ar.AsyncState as Socket;
var length = socket.EndReceive(ar);
if (length==0)
return;
byte[] reallData = new byte[length];
Array.Copy(buffer, reallData, length);
})
------解决方案-------------------- client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);是把这个写成上边的=>这样的 这是包的概念 你试试
------解决方案--------------------MARK,学习一下如何处理2W个长连接
------解决方案--------------------buffer是如何管理的?如何保证每个连接有自己的buffer?
------解决方案--------------------//可以逐渐把1000这个数字加大,比如
this.semaphoreAcceptedClients = new Semaphore(10000, 10000); //测试看能处理多少连接
//连接
public void ClientAccepted(IAsyncResult ar)
{
try
{
var socket = ar.AsyncState as Socket;
var client = socket.EndAccept(ar);
client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);
socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);