日期:2014-05-16  浏览次数:21113 次

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