硬件当然会对最大连接数产生影响,我想知道的是,在排除硬件的影响下,最大能支持多少人同时在线。 我用的是TCP协议,底层代码如下: using System; using System.Net; using System.Net.Sockets; using FlawlessCode.Network.ExtensionMethods;namespace FlawlessCode.Network.SocketServer { /// <summary> /// Listens for socket connection on a given address and port. /// </summary> public class TcpSocketListener : IDisposable { #region Fields private Int32 connectionBacklog; private IPEndPoint endPoint; private Socket listenerSocket; private SocketAsyncEventArgs args; #endregion #region Properties /// <summary> /// Length of the connection backlog. /// </summary> public Int32 ConnectionBacklog { get { return connectionBacklog; } set { lock (this) { if (IsRunning) throw new InvalidOperationException("Property cannot be changed while server running."); else connectionBacklog = value; } } } /// <summary> /// The IPEndPoint to bind the listening socket to. /// </summary> public IPEndPoint EndPoint { get { return endPoint; } set { lock (this) { if (IsRunning) throw new InvalidOperationException("Property cannot be changed while server running."); else endPoint = value; } } } /// <summary> /// Is the class currently listening. /// </summary> public Boolean IsRunning { get { return listenerSocket != null; } } #endregion #region Constructors /// <summary> /// Listens for socket connection on a given address and port. /// </summary> /// <param name="address">The address to listen on.</param> /// <param name="port">The port to listen on.</param> /// <param name="connectionBacklog">The connection backlog.</param> public TcpSocketListener(String address, Int32 port, Int32 connectionBacklog) : this(IPAddress.Parse(address), port, connectionBacklog) { } /// <summary> /// Listens for socket connection on a given address and port. /// </summary> /// <param name="address">The address to listen on.</param> /// <param name="port">The port to listen on.</param> /// <param name="connectionBacklog">The connection backlog.</param> public TcpSocketListener(IPAddress address, Int32 port, Int32 connectionBacklog) : this(new IPEndPoint(address, port), connectionBacklog) { } /// <summary> /// Listens for socket connection on a given address and port. /// </summary> /// <param name="endPoint">The endpoint to listen on.</param> /// <param name="connectionBacklog">The connection backlog.</param> public TcpSocketListener(IPEndPoint endPoint, Int32 connectionBacklog) { this.endPoint = endPoint;
args = new SocketAsyncEventArgs(); args.Completed += SocketAccepted; } #endregion #region Public Methods /// <summary> /// Start listening for socket connections. /// </summary> public void Start() { lock (this) { if (!IsRunning) { listenerSocket = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); listenerSocket.Bind(endPoint); listenerSocket.Listen(connectionBacklog); ListenForConnection(args); } else throw new InvalidOperationException("The Server is already running."); }
} /// <summary> /// Stop listening for socket connections. /// </summary> public void Stop() { lock (this) { if (listenerSocket == null) return; listenerSocket.Close(); listenerSocket = null; } } #endregion
#region Private Methods /// <summary> /// Asynchronously listens for new connections. /// </summary> /// <param name="args"></param> private void ListenForConnection(SocketAsyncEventArgs args) { args.AcceptSocket = null; listenerSocket.InvokeAsyncMethod(new SocketAsyncMethod(listenerSocket.AcceptAsync) , SocketAccepted, args); } /// <summary> /// Invoked when an asynchrounous accept completes. /// </summary> /// <param name="sender">The sender.</param> /// <param name="e">The SocketAsyncEventArgs for the operation.</param> private void SocketAccepted(object sender, SocketAsyncEventArgs e) { SocketError error = e.SocketError; if (e.SocketError == SocketError.OperationAborted) return; //Server was stopped if (e.SocketError == SocketError.Success) { Socket handler = e.AcceptSocket; OnSocketConnected(handler); } lock (this) { ListenForConnection(e); } } #endregion #region Events /// <summary> /// Fired when a new connection is received. /// </summary> public event EventHandler<SocketEventArgs> SocketConnected; /// <summary> /// Fires the SocketConnected event. /// </summary> /// <param name="client">The new client socket.</param> private void OnSocketConnected(Socket client) { if (SocketConnected != null) SocketConnected(this, new SocketEventArgs() { Socket = client }); } #endregion #region IDisposable Members private Boolean disposed = false; ~TcpSocketListener() { Dispose(false); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { Stop(); if (args != null) args.Dispose(); } disposed = true; } } #endregion } }
using System; using System.Collections.Generic; using System.Net.Sockets;namespace FlawlessCode.Network.SocketServer { /// <summary> /// Pools data buffers to prevent both frequent allocation and memory fragmentation /// due to pinning in high volume scenarios. /// See https://blogs.msdn.com/yunjin/archive/2004/01/27/63642.aspx /// </summary> public class BufferPool { Int32 totalBytes; Byte[] buffer; Stack<Int32> freeIndexPool; Int32 currentIndex; Int32 bufferSize; /// <summary> /// Pools data buffers to prevent both frequent allocation and memory fragmentation /// due to pinning in high volume scenarios. /// </summary> /// <param name="numberOfBuffers">The total number of buffers that will be allocated.</param> /// <param name="bufferSize">The size of each buffer.</param> public BufferPool(Int32 numberOfBuffers, Int32 bufferSize) { this.totalBytes = numberOfBuffers * bufferSize; this.bufferSize = bufferSize; currentIndex = 0; freeIndexPool = new Stack<Int32>(); buffer = new Byte[totalBytes]; } /// <summary> /// Checks out some buffer space from the pool. /// </summary> /// <param name="args">The ScoketAsyncEventArgs which needs a buffer.</param> public void CheckOut(SocketAsyncEventArgs args) { lock (freeIndexPool) { if (freeIndexPool.Count > 0) args.SetBuffer(buffer, freeIndexPool.Pop(), bufferSize); else { args.SetBuffer(buffer, currentIndex, bufferSize); currentIndex += bufferSize; } } } /// <summary> /// Checks a buffer back in to the pool. /// </summary> /// <param name="args">The SocketAsyncEventArgs which has finished with it buffer.</param> public void CheckIn(SocketAsyncEventArgs args) { lock (freeIndexPool) { freeIndexPool.Push(args.Offset); args.SetBuffer(null, 0, 0); } } /// <summary> /// The number of available objects in the pool. /// </summary> public int Available { get { lock (freeIndexPool) { return ((totalBytes - currentIndex) / bufferSize) + freeIndexPool.Count; } } } } }
using System; using System.Net.Sockets; using FlawlessCode.Network.ExtensionMethods; using System.Net;namespace FlawlessCode.Network.SocketServer { /// <summary> /// Represents a callback used to inform a listener that a ServerConnection has received data. /// </summary> /// <param name="sender">The sender of the callback.</param> /// <param name="e">The DataEventArgs object containging the received data.</param> public delegate void DataReceivedCallback(ServerConnection sender, DataEventArgs e); /// <summary> /// Represents a callback used to inform a listener that a ServerConnection has disconnected. /// </summary> /// <param name="sender">The sender of the callback.</param> /// <param name="e">The SocketAsyncEventArgs object used by the ServerConnection.</param> public delegate void DisconnectedCallback(ServerConnection sender, SocketAsyncEventArgs e); /// <summary> /// A connection to our server. /// </summary> public class ServerConnection { #region Internal Classes internal class State { public DataReceivedCallback dataReceived; public DisconnectedCallback disconnectedCallback; public Socket socket; } #endregion #region Fields private SocketAsyncEventArgs eventArgs; #endregion #region Constructor /// <summary> /// A connection to our server, always listening asynchronously. /// </summary> /// <param name="socket">The Socket for the connection.</param> /// <param name="args">The SocketAsyncEventArgs for asyncronous recieves.</param> /// <param name="dataReceived">A callback invoked when data is recieved.</param> /// <param name="disconnectedCallback">A callback invoked on disconnection.</param> public ServerConnection(Socket socket, SocketAsyncEventArgs args, DataReceivedCallback dataReceived, DisconnectedCallback disconnectedCallback) { lock (this) { State state = new State() { socket = socket, dataReceived = dataReceived, disconnectedCallback = disconnectedCallback}; eventArgs = args; eventArgs.Completed += ReceivedCompleted; eventArgs.UserToken = state; ListenForData(eventArgs); } } #endregion #region Public Methods /// <summary> /// Disconnects the client. /// </summary> public void Disconnect() { lock (this) { CloseConnection(eventArgs); } } /// <summary> /// Sends data to the client. /// </summary> /// <param name="data">The data to send.</param> /// <param name="offset">The offset into the data.</param> /// <param name="count">The ammount of data to send.</param> public Socket socket; public void SendData(Byte[] data, Int32 offset, Int32 count) { lock (this) { State state = eventArgs.UserToken as State; Socket socket = state.socket; this.socket = socket; if (socket.Connected) socket.Send(data, offset, count, SocketFlags.None); } } public void SendData(Byte[] data) { lock (this) { State state = eventArgs.UserToken as State; Socket socket = state.socket; this.socket = socket; if (socket.Connected) socket.Send(data); } } public void SendData(String data) { lock (this) { State state = eventArgs.UserToken as State; Socket socket = state.socket; this.socket = socket; Byte[] bit = System.Text.Encoding.Default.GetBytes(data + "\0"); if (socket.Connected) socket.Send(bit); } } #endregion #region Private Methods /// <summary> /// Starts and asynchronous recieve. /// </summary> /// <param name="args">The SocketAsyncEventArgs to use.</param> private void ListenForData(SocketAsyncEventArgs args) { lock (this) { Socket socket = (args.UserToken as State).socket; if (socket.Connected) { socket.InvokeAsyncMethod(socket.ReceiveAsync, ReceivedCompleted, args); } } } /// <summary> /// Called when an asynchronous receive has completed. /// </summary> /// <param name="sender">The sender.</param> /// <param name="args">The SocketAsyncEventArgs for the operation.</param> private void ReceivedCompleted(Object sender, SocketAsyncEventArgs args) { if (args.BytesTransferred == 0) { CloseConnection(args); //Graceful disconnect return; } if (args.SocketError != SocketError.Success) { CloseConnection(args); //NOT graceful disconnect return; } State state = args.UserToken as State; Byte[] data = new Byte[args.BytesTransferred]; Array.Copy(args.Buffer, args.Offset, data, 0, data.Length); OnDataReceived(data, args.RemoteEndPoint as IPEndPoint, state.dataReceived); ListenForData(args); } /// <summary> /// Closes the connection. /// </summary> /// <param name="args">The SocketAsyncEventArgs for the connection.</param> private void CloseConnection(SocketAsyncEventArgs args) { State state = args.UserToken as State; Socket socket = state.socket; try { socket.Shutdown(SocketShutdown.Both); } catch { } // throws if client process has already closed socket.Close(); socket = null; args.Completed -= ReceivedCompleted; //MUST Remember This! OnDisconnected(args, state.disconnectedCallback); } #endregion #region Events /// <summary> /// Fires the DataReceivedCallback. /// </summary> /// <param name="data">The data which was received.</param> /// <param name="remoteEndPoint">The address the data came from.</param> /// <param name="callback">The callback.</param> private void OnDataReceived(Byte[] data, IPEndPoint remoteEndPoint, DataReceivedCallback callback) { callback(this, new DataEventArgs() { RemoteEndPoint = remoteEndPoint, Data = data }); } /// <summary> /// Fires the DisconnectedCallback. /// </summary> /// <param name="args">The SocketAsyncEventArgs for this connection.</param> /// <param name="callback">The callback.</param> private void OnDisconnected(SocketAsyncEventArgs args, DisconnectedCallback callback) { callback(this, args); } #endregion } }
你看看是否是系统有连接数限制,如tcpip的连接
我用的是TCP协议,底层代码如下:
using System;
using System.Net;
using System.Net.Sockets;
using FlawlessCode.Network.ExtensionMethods;namespace FlawlessCode.Network.SocketServer
{
/// <summary>
/// Listens for socket connection on a given address and port.
/// </summary>
public class TcpSocketListener : IDisposable
{
#region Fields
private Int32 connectionBacklog;
private IPEndPoint endPoint; private Socket listenerSocket;
private SocketAsyncEventArgs args;
#endregion #region Properties
/// <summary>
/// Length of the connection backlog.
/// </summary>
public Int32 ConnectionBacklog
{
get { return connectionBacklog; }
set
{
lock (this)
{
if (IsRunning)
throw new InvalidOperationException("Property cannot be changed while server running.");
else
connectionBacklog = value;
}
}
}
/// <summary>
/// The IPEndPoint to bind the listening socket to.
/// </summary>
public IPEndPoint EndPoint
{
get { return endPoint; }
set
{
lock (this)
{
if (IsRunning)
throw new InvalidOperationException("Property cannot be changed while server running.");
else
endPoint = value;
}
}
}
/// <summary>
/// Is the class currently listening.
/// </summary>
public Boolean IsRunning
{
get { return listenerSocket != null; }
}
#endregion #region Constructors
/// <summary>
/// Listens for socket connection on a given address and port.
/// </summary>
/// <param name="address">The address to listen on.</param>
/// <param name="port">The port to listen on.</param>
/// <param name="connectionBacklog">The connection backlog.</param>
public TcpSocketListener(String address, Int32 port, Int32 connectionBacklog)
: this(IPAddress.Parse(address), port, connectionBacklog)
{ }
/// <summary>
/// Listens for socket connection on a given address and port.
/// </summary>
/// <param name="address">The address to listen on.</param>
/// <param name="port">The port to listen on.</param>
/// <param name="connectionBacklog">The connection backlog.</param>
public TcpSocketListener(IPAddress address, Int32 port, Int32 connectionBacklog)
: this(new IPEndPoint(address, port), connectionBacklog)
{ }
/// <summary>
/// Listens for socket connection on a given address and port.
/// </summary>
/// <param name="endPoint">The endpoint to listen on.</param>
/// <param name="connectionBacklog">The connection backlog.</param>
public TcpSocketListener(IPEndPoint endPoint, Int32 connectionBacklog)
{
this.endPoint = endPoint;
args = new SocketAsyncEventArgs();
args.Completed += SocketAccepted;
}
#endregion #region Public Methods
/// <summary>
/// Start listening for socket connections.
/// </summary>
public void Start()
{
lock (this)
{
if (!IsRunning)
{
listenerSocket = new Socket(
AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listenerSocket.Bind(endPoint);
listenerSocket.Listen(connectionBacklog);
ListenForConnection(args);
}
else
throw new InvalidOperationException("The Server is already running.");
}
} /// <summary>
/// Stop listening for socket connections.
/// </summary>
public void Stop()
{
lock (this)
{
if (listenerSocket == null)
return;
listenerSocket.Close();
listenerSocket = null;
}
}
#endregion
#region Private Methods
/// <summary>
/// Asynchronously listens for new connections.
/// </summary>
/// <param name="args"></param>
private void ListenForConnection(SocketAsyncEventArgs args)
{
args.AcceptSocket = null; listenerSocket.InvokeAsyncMethod(new SocketAsyncMethod(listenerSocket.AcceptAsync)
, SocketAccepted, args);
}
/// <summary>
/// Invoked when an asynchrounous accept completes.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The SocketAsyncEventArgs for the operation.</param>
private void SocketAccepted(object sender, SocketAsyncEventArgs e)
{
SocketError error = e.SocketError;
if (e.SocketError == SocketError.OperationAborted)
return; //Server was stopped if (e.SocketError == SocketError.Success)
{
Socket handler = e.AcceptSocket;
OnSocketConnected(handler);
} lock (this)
{
ListenForConnection(e);
}
}
#endregion #region Events
/// <summary>
/// Fired when a new connection is received.
/// </summary>
public event EventHandler<SocketEventArgs> SocketConnected;
/// <summary>
/// Fires the SocketConnected event.
/// </summary>
/// <param name="client">The new client socket.</param>
private void OnSocketConnected(Socket client)
{
if (SocketConnected != null)
SocketConnected(this, new SocketEventArgs() { Socket = client });
}
#endregion #region IDisposable Members
private Boolean disposed = false; ~TcpSocketListener()
{
Dispose(false);
} public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} private void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
Stop();
if (args != null)
args.Dispose();
} disposed = true;
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Net.Sockets;namespace FlawlessCode.Network.SocketServer
{
/// <summary>
/// Pools data buffers to prevent both frequent allocation and memory fragmentation
/// due to pinning in high volume scenarios.
/// See https://blogs.msdn.com/yunjin/archive/2004/01/27/63642.aspx
/// </summary>
public class BufferPool
{
Int32 totalBytes;
Byte[] buffer;
Stack<Int32> freeIndexPool;
Int32 currentIndex;
Int32 bufferSize; /// <summary>
/// Pools data buffers to prevent both frequent allocation and memory fragmentation
/// due to pinning in high volume scenarios.
/// </summary>
/// <param name="numberOfBuffers">The total number of buffers that will be allocated.</param>
/// <param name="bufferSize">The size of each buffer.</param>
public BufferPool(Int32 numberOfBuffers, Int32 bufferSize)
{
this.totalBytes = numberOfBuffers * bufferSize;
this.bufferSize = bufferSize; currentIndex = 0;
freeIndexPool = new Stack<Int32>();
buffer = new Byte[totalBytes];
} /// <summary>
/// Checks out some buffer space from the pool.
/// </summary>
/// <param name="args">The ScoketAsyncEventArgs which needs a buffer.</param>
public void CheckOut(SocketAsyncEventArgs args)
{
lock (freeIndexPool)
{
if (freeIndexPool.Count > 0)
args.SetBuffer(buffer, freeIndexPool.Pop(), bufferSize);
else
{
args.SetBuffer(buffer, currentIndex, bufferSize);
currentIndex += bufferSize;
}
}
} /// <summary>
/// Checks a buffer back in to the pool.
/// </summary>
/// <param name="args">The SocketAsyncEventArgs which has finished with it buffer.</param>
public void CheckIn(SocketAsyncEventArgs args)
{
lock (freeIndexPool)
{
freeIndexPool.Push(args.Offset);
args.SetBuffer(null, 0, 0);
}
} /// <summary>
/// The number of available objects in the pool.
/// </summary>
public int Available
{
get
{
lock (freeIndexPool)
{
return ((totalBytes - currentIndex) / bufferSize) + freeIndexPool.Count;
}
}
}
}
}
using System.Net.Sockets;
using FlawlessCode.Network.ExtensionMethods;
using System.Net;namespace FlawlessCode.Network.SocketServer
{
/// <summary>
/// Represents a callback used to inform a listener that a ServerConnection has received data.
/// </summary>
/// <param name="sender">The sender of the callback.</param>
/// <param name="e">The DataEventArgs object containging the received data.</param>
public delegate void DataReceivedCallback(ServerConnection sender, DataEventArgs e);
/// <summary>
/// Represents a callback used to inform a listener that a ServerConnection has disconnected.
/// </summary>
/// <param name="sender">The sender of the callback.</param>
/// <param name="e">The SocketAsyncEventArgs object used by the ServerConnection.</param>
public delegate void DisconnectedCallback(ServerConnection sender, SocketAsyncEventArgs e); /// <summary>
/// A connection to our server.
/// </summary>
public class ServerConnection
{
#region Internal Classes
internal class State
{
public DataReceivedCallback dataReceived;
public DisconnectedCallback disconnectedCallback;
public Socket socket;
}
#endregion #region Fields
private SocketAsyncEventArgs eventArgs;
#endregion #region Constructor
/// <summary>
/// A connection to our server, always listening asynchronously.
/// </summary>
/// <param name="socket">The Socket for the connection.</param>
/// <param name="args">The SocketAsyncEventArgs for asyncronous recieves.</param>
/// <param name="dataReceived">A callback invoked when data is recieved.</param>
/// <param name="disconnectedCallback">A callback invoked on disconnection.</param>
public ServerConnection(Socket socket, SocketAsyncEventArgs args, DataReceivedCallback dataReceived,
DisconnectedCallback disconnectedCallback)
{
lock (this)
{
State state = new State() { socket = socket, dataReceived = dataReceived,
disconnectedCallback = disconnectedCallback}; eventArgs = args;
eventArgs.Completed += ReceivedCompleted;
eventArgs.UserToken = state; ListenForData(eventArgs);
}
}
#endregion #region Public Methods
/// <summary>
/// Disconnects the client.
/// </summary>
public void Disconnect()
{
lock (this)
{
CloseConnection(eventArgs);
}
} /// <summary>
/// Sends data to the client.
/// </summary>
/// <param name="data">The data to send.</param>
/// <param name="offset">The offset into the data.</param>
/// <param name="count">The ammount of data to send.</param>
public Socket socket;
public void SendData(Byte[] data, Int32 offset, Int32 count)
{
lock (this)
{
State state = eventArgs.UserToken as State;
Socket socket = state.socket;
this.socket = socket;
if (socket.Connected)
socket.Send(data, offset, count, SocketFlags.None);
}
}
public void SendData(Byte[] data)
{
lock (this)
{
State state = eventArgs.UserToken as State;
Socket socket = state.socket;
this.socket = socket;
if (socket.Connected)
socket.Send(data);
}
}
public void SendData(String data)
{
lock (this)
{
State state = eventArgs.UserToken as State;
Socket socket = state.socket;
this.socket = socket;
Byte[] bit = System.Text.Encoding.Default.GetBytes(data + "\0");
if (socket.Connected)
socket.Send(bit);
}
}
#endregion #region Private Methods
/// <summary>
/// Starts and asynchronous recieve.
/// </summary>
/// <param name="args">The SocketAsyncEventArgs to use.</param>
private void ListenForData(SocketAsyncEventArgs args)
{
lock (this)
{
Socket socket = (args.UserToken as State).socket;
if (socket.Connected)
{
socket.InvokeAsyncMethod(socket.ReceiveAsync,
ReceivedCompleted, args);
}
}
} /// <summary>
/// Called when an asynchronous receive has completed.
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="args">The SocketAsyncEventArgs for the operation.</param>
private void ReceivedCompleted(Object sender, SocketAsyncEventArgs args)
{
if (args.BytesTransferred == 0)
{
CloseConnection(args); //Graceful disconnect
return;
}
if (args.SocketError != SocketError.Success)
{
CloseConnection(args); //NOT graceful disconnect
return;
} State state = args.UserToken as State; Byte[] data = new Byte[args.BytesTransferred];
Array.Copy(args.Buffer, args.Offset, data, 0, data.Length);
OnDataReceived(data, args.RemoteEndPoint as IPEndPoint, state.dataReceived); ListenForData(args);
} /// <summary>
/// Closes the connection.
/// </summary>
/// <param name="args">The SocketAsyncEventArgs for the connection.</param>
private void CloseConnection(SocketAsyncEventArgs args)
{
State state = args.UserToken as State;
Socket socket = state.socket;
try
{
socket.Shutdown(SocketShutdown.Both);
}
catch { } // throws if client process has already closed
socket.Close();
socket = null; args.Completed -= ReceivedCompleted; //MUST Remember This!
OnDisconnected(args, state.disconnectedCallback);
}
#endregion #region Events
/// <summary>
/// Fires the DataReceivedCallback.
/// </summary>
/// <param name="data">The data which was received.</param>
/// <param name="remoteEndPoint">The address the data came from.</param>
/// <param name="callback">The callback.</param>
private void OnDataReceived(Byte[] data, IPEndPoint remoteEndPoint, DataReceivedCallback callback)
{
callback(this, new DataEventArgs() { RemoteEndPoint = remoteEndPoint, Data = data });
} /// <summary>
/// Fires the DisconnectedCallback.
/// </summary>
/// <param name="args">The SocketAsyncEventArgs for this connection.</param>
/// <param name="callback">The callback.</param>
private void OnDisconnected(SocketAsyncEventArgs args, DisconnectedCallback callback)
{
callback(this, args);
}
#endregion
}
}
底层代码用的是缓冲池+异步通信,采用select模式,不过这种模式应该存在弊端。
Windows开到200个线程,性能会急剧下降的
能开到几百个连接,已经优化得算是不错了。。==================================
引用自一个朋友的话。。
也就是说,对于简单的聊天服务器,最少两个线程就可以服务了(而且服务的Client数量理论上不受限制)。
对于Server,进来一个Client,启动一个单独的线程对其服务。这样的话,进来的Client多了,系统资源很容易被耗尽。
祝你好运。
在Windows平台,性能比较好的Socket, 同时在线人数能达多少?
windows也能支持 3000-4000 的长连接并发.
你给的代码太长,是在难读.
至于怎么修改这个限制,还不清楚
server2003的连接数理论上应该有65355,可到不了。
具体最大能到多少,没有测试过。最后硬件也是有一定的关系。俺的破本子弄到300就game over了。
后来发现问题出在数据库上,在做压力测试时,不停的login,logout等操作都要读写数据库,CPU都用在处理数据库上了。
我想,如果再优化一下数据库的读写方面操作,可能还能压到更高。
这是瞎话... 直接从我这个IBM笔记本上实验的 java NIO socket 就可以连3000个...
不知道你XP有连接500个左右的限制 这样的结论是怎么得出来的.还是你的XP系统和我的不一样么?