- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在测试以下两种情况,一种有效,但另一种无效。我有套接字服务器和套接字客户端应用程序在两台不同的机器上运行
这两个场景都使用了 socketasynceventargs
场景 1(有效)循环创建 40k 套接字客户端,等待所有连接建立,然后所有客户端同时向服务器发送消息并从服务器接收响应 10 次(即发送/接收发生 10 次)。
场景 2(不起作用。我收到很多连接拒绝错误)在循环中创建 40k 套接字客户端,并在每个客户端连接后立即向服务器发送/接收相同的 10 条消息,而不是等待 40k 连接建立。
我无法弄清楚为什么我的第二种情况会失败。我知道在场景 1 中,服务器在建立所有 40k 连接之前不会做太多事情。但它能够同时与所有客户端通信。有什么想法吗??
感谢您的耐心等待。
这里是套接字服务器代码
public class SocketServer
{
private static System.Timers.Timer MonitorTimer = new System.Timers.Timer();
public static SocketServerMonitor socket_monitor = new SocketServerMonitor();
private int m_numConnections;
private int m_receiveBufferSize;
public static BufferManager m_bufferManager;
Socket listenSocket;
public static SocketAsyncEventArgsPool m_readWritePool;
public static int m_numConnectedSockets;
private int cnt = 0;
public static int Closecalled=0;
public SocketServer(int numConnections, int receiveBufferSize)
{
m_numConnectedSockets = 0;
m_numConnections = numConnections;
m_receiveBufferSize = receiveBufferSize;
m_bufferManager = new BufferManager(receiveBufferSize * numConnections ,
receiveBufferSize);
m_readWritePool = new SocketAsyncEventArgsPool(numConnections);
}
public void Init()
{
MonitorTimer.Interval = 30000;
MonitorTimer.Start();
MonitorTimer.Elapsed += new System.Timers.ElapsedEventHandler(socket_monitor.Log);
m_bufferManager.InitBuffer();
SocketAsyncEventArgs readWriteEventArg;
for (int i = 0; i < m_numConnections; i++)
{
readWriteEventArg = new SocketAsyncEventArgs();
m_readWritePool.Push(readWriteEventArg);
}
}
public void Start(IPEndPoint localEndPoint)
{
listenSocket = new Socket(localEndPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
listenSocket.Bind(localEndPoint);
listenSocket.Listen(1000);
StartAccept(null);
}
public void Stop()
{
if (listenSocket == null)
return;
listenSocket.Close();
listenSocket = null;
Thread.Sleep(15000);
}
private void StartAccept(SocketAsyncEventArgs acceptEventArg)
{
if (acceptEventArg == null)
{
acceptEventArg = new SocketAsyncEventArgs();
acceptEventArg.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptEventArg_Completed);
}
else
{
// socket must be cleared since the context object is being reused
acceptEventArg.AcceptSocket = null;
}
try
{
bool willRaiseEvent = listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}
catch (Exception e)
{
}
}
void AcceptEventArg_Completed(object sender, SocketAsyncEventArgs e)
{
ProcessAccept(e);
}
private void ProcessAccept(SocketAsyncEventArgs e)
{
Interlocked.Increment(ref m_numConnectedSockets);
socket_monitor.IncSocketsConnected();
SocketAsyncEventArgs readEventArgs = m_readWritePool.Pop();
m_bufferManager.SetBuffer(readEventArgs);
readEventArgs.UserToken = new AsyncUserToken { id = cnt++, StarTime = DateTime.Now };
readEventArgs.AcceptSocket = e.AcceptSocket;
SocketHandler handler=new SocketHandler(readEventArgs);
StartAccept(e);
}
}
class SocketHandler
{
private SocketAsyncEventArgs _socketEventArgs;
public SocketHandler(SocketAsyncEventArgs socketAsyncEventArgs)
{
_socketEventArgs = socketAsyncEventArgs;
_socketEventArgs.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed);
StartReceive(_socketEventArgs);
}
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
}
private void ProcessReceive(SocketAsyncEventArgs e)
{
// check if the remote host closed the connection
AsyncUserToken token = (AsyncUserToken)e.UserToken;
//token.StarTime = DateTime.Now;
if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success)
{
// process the data here
//reply to client
byte[] AckData1 = BitConverter.GetBytes(1);
SendData(AckData1, 0, AckData1.Length, e);
StartReceive(e);
}
else
{
CloseClientSocket(e);
}
}
private void IO_Completed(object sender, SocketAsyncEventArgs e)
{
// determine which type of operation just completed and call the associated handler
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
case SocketAsyncOperation.Send:
ProcessSend(e);
break;
default:
throw new ArgumentException("The last operation completed on the socket was not a receive or send");
}
}
private void CloseClientSocket(SocketAsyncEventArgs e)
{
AsyncUserToken token = e.UserToken as AsyncUserToken;
// close the socket associated with the client
try
{
e.AcceptSocket.Shutdown(SocketShutdown.Send);
}
catch (Exception ex)
{
}
e.AcceptSocket.Close();
Interlocked.Decrement(ref SocketServer.m_numConnectedSockets);
SocketServer.socket_monitor.DecSocketsConnected();
SocketServer.m_bufferManager.FreeBuffer(e);
e.Completed -= new EventHandler<SocketAsyncEventArgs>(IO_Completed);
SocketServer.m_readWritePool.Push(e);
}
public void SendData(Byte[] data, Int32 offset, Int32 count, SocketAsyncEventArgs args)
{
try
{
Socket socket = args.AcceptSocket;
if (socket.Connected)
{
var i = socket.Send(data, offset, count, SocketFlags.None);
}
}
catch (Exception Ex)
{
}
}
}
这里是在connectcallback方法中抛出错误的客户端代码
// State object for receiving data from remote device.
public class StateObject
{
// Client socket.
public Socket workSocket = null;
// Size of receive buffer.
public const int BufferSize = 256;
// Receive buffer.
public byte[] buffer = new byte[BufferSize];
// Received data string.
public StringBuilder sb = new StringBuilder();
public int count = 0;
}
public class AsynchronousClient
{
// The port number for the remote device.
private const int port = 11000;
private static int closecalled = 0;
private static bool wait = true;
// ManualResetEvent instances signal completion.
private static ManualResetEvent connectDone =
new ManualResetEvent(false);
private static ManualResetEvent sendDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
// The response from the remote device.
private static String response = String.Empty;
private static void StartClient(Socket client, IPEndPoint remoteEP)
{
// Connect to a remote device.
try
{
// Connect to the remote endpoint.
client.BeginConnect(remoteEP,
new AsyncCallback(ConnectCallback), new StateObject { workSocket = client });
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
StateObject state = (StateObject)ar.AsyncState;
var client = state.workSocket;
// Complete the connection.
client.EndConnect(ar);
var data = "AA5500C08308353816050322462F01020102191552E7D3FA52E7D3FB1FF85BF1FE9F201000004AB80000000500060800001EFFB72F0D00002973620000800000FFFFFFFF00009D6D00003278002EE16D0000018500000000000000000000003A0000000100000000828C80661FF8B436FE9EA9FC000000120000000700000000000000000000000400000000000000000000000000000000000000000000281E0000327800000000000000000000000000AF967D00000AEA000000000000000000000000";
Send(state, data);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Receive(StateObject state)
{
try
{
Socket client = state.workSocket;
// Begin receiving the data from the remote device.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void ReceiveCallback(IAsyncResult ar)
{
try
{
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Read data from the remote device.
int bytesRead = client.EndReceive(ar);
//if (wait)
//{
// connectDone.WaitOne();
//}
if (bytesRead > 0)
{
state.count = state.count + 1;
byte[] b = new byte[bytesRead];
Array.Copy(state.buffer, b, 1);
if (b[0] == 1)
{
if (state.count < 10)
{
var data = "AA5500C08308353816050322462F01020102191552E7D3FA52E7D3FB1FF85BF1FE9F201000004AB80000000500060800001EFFB72F0D00002973620000800000FFFFFFFF00009D6D00003278002EE16D0000018500000000000000000000003A0000000100000000828C80661FF8B436FE9EA9FC000000120000000700000000000000000000000400000000000000000000000000000000000000000000281E0000327800000000000000000000000000AF967D00000AEA000000000000000000000000";
Send(state, data);
}
else
{
Interlocked.Increment(ref closecalled);
Console.WriteLine("closecalled:-" + closecalled + " at " + DateTime.Now);
client.Close();
}
}
else
{
// Get the rest of the data.
client.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
new AsyncCallback(ReceiveCallback), state);
}
}
else
{
client.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void Send(StateObject state, String data)
{
try
{
Socket client = state.workSocket;
var hexlen = data.Length;
byte[] byteData = new byte[hexlen / 2];
int[] hexarray = new int[hexlen / 2];
int i = 0;
int k = 0;
//create the byte array
while (i < data.Length / 2)
{
string first = data[i].ToString();
i++;
string second = data[i].ToString();
string x = first + second;
byteData[k] = (byte)Convert.ToInt32(x, 16);
i++;
k++;
}
// Begin sending the data to the remote device.
client.BeginSend(byteData, 0, byteData.Length, 0,
new AsyncCallback(SendCallback), state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
private static void SendCallback(IAsyncResult ar)
{
try
{
// Retrieve the socket from the state object.
StateObject state = (StateObject)ar.AsyncState;
Socket client = state.workSocket;
// Complete sending the data to the remote device.
int bytesSent = client.EndSend(ar);
Receive(state);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public static int Main(String[] args)
{
Start();
Console.ReadLine();
return 0;
}
private static void Start()
{
IPAddress ipaddress = IPAddress.Parse("10.20.2.152");
IPEndPoint remoteEP = new IPEndPoint(ipaddress, port);
for (int i = 0; i < 40000; i++)
{
Thread.Sleep(1);
// Create a TCP/IP socket.
try
{
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
StartClient(client, remoteEP);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
if (i == 39999)
{
Console.WriteLine("made all conns at " + DateTime.Now);
}
}
}
}
最佳答案
我会使用线性队列来接受传入连接。像这样:
public async Task Accept40KClients()
{
for (int i = 0; i < 40000; i++)
{
// Await this here -------v
bool willRaiseEvent = await listenSocket.AcceptAsync(acceptEventArg);
if (!willRaiseEvent)
{
ProcessAccept(acceptEventArg);
}
}
}
如果这还不够快,也许您可以一次等待 10 次,但我认为这已经足够了……虽然我在这方面可能是错的。
关于c# SocketAsyncEventArgs 阻塞 ReceiveAsync 处理程序中的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24809358/
我有时会收到此错误: An asynchronous socket operation is already in progress using this SocketAsyncEventArgs i
我试图理解 C# 中的“SocketAsyncEventArgs”类。 http://msdn.microsoft.com/en-us/library/system.net.sockets.socke
我的 SocketAsyncEventArgs 类有问题..问题是当我尝试发送 8K 数据时例如在互联网上,套接字有时只发送 1K 或 2K,我知道这是正常的TCP 套接字和一次发送并不能保证一次接收
我正在为我的分布式系统编写消息层。我正在使用 IOCP,即 Socket.XXXAsync 方法。 下面是一些与我正在做的非常接近的东西(事实上,我的接收函数是基于他的): http://vadmys
在我的场景中,有许多客户端的 tcp 套接字连接到服务器。服务器从所有套接字接收 ReceiveAsync(),当回调被无误调用时,解析接收到的数据。如果一个套接字接收到的数据是某种类型的消息,则接收
我在 SocketAsyncEventArgs buffer is full of zeroes 中描述了类似的问题其中我的 SocketAsyncEventArgs UDP 服务器的实现接收具有以下
似乎无法在 .NET Socket 类的 AcceptAsync() 方法上指定超时。它接受一个 SocketAsyncEventArgs if (!socket.AcceptAsync(awaita
我最初在发送数据时遇到了竞争条件,问题是我允许使用多个 SocketAsyncEventArgs 来发送数据,但是第一个数据包在第二个数据包之前没有完全发送,这是因为我有它如果数据不适合缓冲区,它会循
我正在使用 SocketAsyncEventArgs 与数百种设备进行通信(其中大部分通过 GPRS)。有时,它们中的一些会停止响应,而且我似乎无法使操作超时,因为文档指出超时选项(即 SocketO
是否有正当理由不使用 TcpListener 而不是 SocketAsyncEventArgs 来实现高性能/高吞吐量 TCP 服务器? 我已经使用 SocketAsyncEventArgs 实现了这
好吧,我读了很多关于编写高可扩展服务器的问题,但我从来没有真正找到一个好的答案。无论如何,我想创建一个可扩展的客户端,它可以处理大量数据和连接。我创建的是一个使用 SocketAsyncEventAr
我四处寻找,很惊讶地发现绝对没有可以回答这个问题: 如何在使用 SocketAsyncEventArgs 时实现 SSL/TLS(或类似)加密?我确实读过,理论上可以使用SslStream 和“作弊”
所以我已经用 SocketAsyncEventArgs 和 socket.***Async 方法编写了一个 tcp 服务器。但我确实喜欢使用 Stream.ReadAsync 和 Stream.Wri
当使用“SocketAsyncEventArgs”类和 ReadAsync 时,我应该将读取缓冲区放在哪里以及将发送缓冲区放在哪里?或者我只能一次阅读或发送而不是两者?我有点困惑。 最佳答案 我认为您
我想使用 SocketAsyncEventArgs 事件创建一个异步套接字服务器。 服务器应该同时管理大约 1000 个连接。处理每个数据包逻辑的最佳方式是什么? 服务器设计基于this MSDN e
我一直在使用.NET 3.5异步套接字API,发现所有* Async方法都返回一个 bool 值,如果该操作同步完成,则它为false。 我对如何/为什么会发生这种情况感到困惑。这并不总是错误的情况,
我正在测试以下两种情况,一种有效,但另一种无效。我有套接字服务器和套接字客户端应用程序在两台不同的机器上运行 这两个场景都使用了 socketasynceventargs 场景 1(有效)循环创建 4
我有一个使用 SocketAsyncEventArgs 异步接收 UDP 数据包的标准实现。我从文档和一些谷歌搜索中不明白的是,我是否应该在回调本身内部完成处理消息的实际工作,比如 this comm
我正致力于使用 IOCP 和 SocketAsyncEventArgs 实现高性能服务器。据我所知,使用这种方法获取 SSL 并不“容易”,因为我发现您要么需要自己实现 SSL,要么以某种方式将使用
我看不到 pooled SocketAsyncEventArgs样式帮助我减少了为许多并发连接提供服务的服务器的内存消耗。 是的,它提供了 MS 的 Begin/End 样式的替代方案,上述 MSDN
我是一名优秀的程序员,十分优秀!