private void DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer, bool expectedToTimeout = false) { int port; Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp); using (SocketUdpServer server = new SocketUdpServer(_log, listenOn, dualModeServer, out port)) { // Send a few packets, in case they aren't delivered reliably. for (int i = 0; i < Configuration.UDPRedundancy; i++) { using (ManualResetEvent waitHandle = new ManualResetEvent(false)) { SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(connectTo, port); args.SetBuffer(new byte[1], 0, 1); args.UserToken = waitHandle; args.Completed += AsyncCompleted; bool async = client.SendToAsync(args); if (async) { Assert.True(waitHandle.WaitOne(Configuration.PassingTestTimeout), "Timeout while waiting for connection"); } Assert.Equal(1, args.BytesTransferred); if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } } } bool success = server.WaitHandle.WaitOne(expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout); // Make sure the bytes were received if (!success) { throw new TimeoutException(); } } }
private IPPacketInformation GetNonDefaultIPPacketInformation() { const int ReceiveTimeout = 5000; using (var receiver = new Socket(SocketType.Dgram, ProtocolType.Udp)) using (var sender = new Socket(SocketType.Dgram, ProtocolType.Udp)) { int port = receiver.BindToAnonymousPort(IPAddress.Loopback); var waitHandle = new ManualResetEvent(false); SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs { RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port), UserToken = waitHandle }; receiveArgs.SetBuffer(new byte[1], 0, 1); receiveArgs.Completed += (_, args) => ((ManualResetEvent)args.UserToken).Set(); Assert.True(receiver.ReceiveMessageFromAsync(receiveArgs)); sender.SendTo(new byte[1], new IPEndPoint(IPAddress.Loopback, port)); Assert.True(waitHandle.WaitOne(ReceiveTimeout)); return receiveArgs.ReceiveMessageFromPacketInfo; } }
private IPPacketInformation GetNonDefaultIPPacketInformation() { const int ReceiveTimeout = 5000; using (var receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) using (var sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { int port = receiver.BindToAnonymousPort(IPAddress.Loopback); var waitHandle = new ManualResetEvent(false); SocketAsyncEventArgs receiveArgs = new SocketAsyncEventArgs { RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, port), UserToken = waitHandle }; receiveArgs.SetBuffer(new byte[1], 0, 1); receiveArgs.Completed += (_, args) => ((ManualResetEvent)args.UserToken).Set(); Assert.True(receiver.ReceiveMessageFromAsync(receiveArgs)); // Send a few packets, in case they aren't delivered reliably. for (int i = 0; i < Configuration.UDPRedundancy; i++) { sender.SendTo(new byte[1], new IPEndPoint(IPAddress.Loopback, port)); } Assert.True(waitHandle.WaitOne(ReceiveTimeout)); return receiveArgs.ReceiveMessageFromPacketInfo; } }
private SocketAsyncEventArgs NewBuffer() { SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.SetBuffer(new byte[1024], 0, 1024); return e; }
/// <summary> /// Connects to the server and begins listening for time updates. /// </summary> public void BeginRequestTime() { byte[] buffer = new byte[48]; buffer[0] = 0x1B; for (var i = 1; i < buffer.Length; ++i) { buffer[i] = 0; } var endPoint = new DnsEndPoint(_ServerAddress, 123); _Socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); var socketArgs = new SocketAsyncEventArgs() { RemoteEndPoint = endPoint }; socketArgs.Completed += (o, e) => { if (e.SocketError == SocketError.Success) { var sArgs = new SocketAsyncEventArgs() { RemoteEndPoint = endPoint }; sArgs.Completed += new EventHandler<SocketAsyncEventArgs>(sArgs_Completed); sArgs.SetBuffer(buffer, 0, buffer.Length); sArgs.UserToken = buffer; _Socket.SendAsync(sArgs); } }; _Socket.ConnectAsync(socketArgs); }
public void Success() { ManualResetEvent completed = new ManualResetEvent(false); if (Socket.OSSupportsIPv4) { using (Socket receiver = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp)) { int port = receiver.BindToAnonymousPort(IPAddress.Loopback); receiver.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true); Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); sender.Bind(new IPEndPoint(IPAddress.Loopback, 0)); sender.SendTo(new byte[1024], new IPEndPoint(IPAddress.Loopback, port)); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(IPAddress.Any, 0); args.SetBuffer(new byte[1024], 0, 1024); args.Completed += OnCompleted; args.UserToken = completed; Assert.True(receiver.ReceiveMessageFromAsync(args)); Assert.True(completed.WaitOne(Configuration.PassingTestTimeout), "Timeout while waiting for connection"); Assert.Equal(1024, args.BytesTransferred); Assert.Equal(sender.LocalEndPoint, args.RemoteEndPoint); Assert.Equal(((IPEndPoint)sender.LocalEndPoint).Address, args.ReceiveMessageFromPacketInfo.Address); sender.Dispose(); } } }
//生成自定义AsyncEventArg private SocketAsyncEventArgs makeSocketAsyncEventArgs() { SocketAsyncEventArgs re = new SocketAsyncEventArgs(); re.UserToken = new AsyncUserToken(m_userTokenBufferLength); re.SetBuffer(((AsyncUserToken)re.UserToken).buffer, 0, m_userTokenBufferLength); re.Completed += new EventHandler<SocketAsyncEventArgs>(IO_Completed); return re; }
public async Task ReuseSocketAsyncEventArgs_SameInstance_MultipleSockets() { using (var listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { listen.Bind(new IPEndPoint(IPAddress.Loopback, 0)); listen.Listen(1); Task<Socket> acceptTask = listen.AcceptAsync(); await Task.WhenAll( acceptTask, client.ConnectAsync(new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)listen.LocalEndPoint).Port))); using (Socket server = await acceptTask) { TaskCompletionSource<bool> tcs = null; var args = new SocketAsyncEventArgs(); args.SetBuffer(new byte[1024], 0, 1024); args.Completed += (_,__) => tcs.SetResult(true); for (int i = 1; i <= 10; i++) { tcs = new TaskCompletionSource<bool>(); args.Buffer[0] = (byte)i; args.SetBuffer(0, 1); if (server.SendAsync(args)) { await tcs.Task; } args.Buffer[0] = 0; tcs = new TaskCompletionSource<bool>(); if (client.ReceiveAsync(args)) { await tcs.Task; } Assert.Equal(1, args.BytesTransferred); Assert.Equal(i, args.Buffer[0]); } } } }
private static void OnOperationCompleted(object sender, SocketAsyncEventArgs args) { Assert.Equal(SocketError.Success, args.SocketError); switch (args.LastOperation) { case SocketAsyncOperation.Accept: { Socket client = args.AcceptSocket; args.SetBuffer(new byte[1], 0, 1); args.UserToken = client; Assert.True(client.ReceiveAsync(args)); break; } case SocketAsyncOperation.Receive: { var client = (Socket)args.UserToken; if (args.BytesTransferred == 0) { client.Dispose(); break; } Assert.True(client.SendAsync(args)); break; } case SocketAsyncOperation.Send: { var client = (Socket)args.UserToken; Assert.True(args.BytesTransferred == args.Buffer.Length); Assert.True(client.ReceiveAsync(args)); break; } } }
public static void ReceiveAsync(this Socket socket, SocketAsyncEventArgs eventArgs, byte[] buffer, int offset, int count, SocketFlags flags, Action<int> handler) { EventHandler<SocketAsyncEventArgs> wrappedHandler = null; wrappedHandler = (_, args) => { Assert.Equal(SocketError.Success, args.SocketError); int received = args.BytesTransferred; args.SetBuffer(null, 0, 0); args.SocketFlags = SocketFlags.None; args.Completed -= wrappedHandler; handler(received); }; eventArgs.SetBuffer(buffer, offset, count); eventArgs.SocketFlags = flags; eventArgs.Completed += wrappedHandler; if (!socket.ReceiveAsync(eventArgs)) { wrappedHandler(null, eventArgs); } }
private void ReceiveCompleted(SocketAsyncEventArgs args) { try { MoreToRead: var state = (Connection)args.UserToken; if (args.BytesTransferred > 0 && args.SocketError == SocketError.Success) { if (state != null) { state.Seen(); // update LastSeen } Interlocked.Add(ref totalBytesReceived, args.BytesTransferred); if (MaxIncomingQuota > 0 && state.IncomingBufferedLength + args.BytesTransferred > MaxIncomingQuota) { throw new InvalidOperationException("Incoming buffer exceeded"); } #if VERBOSE Debug.WriteLine("Received: " + BitConverter.ToString(args.Buffer, args.Offset, args.BytesTransferred)); #endif state.AppendIncoming(context, args.Buffer, args.Offset, args.BytesTransferred); var tmp = args.Buffer; bool recycle = args.Count == tmp.Length; // we pwn it args.SetBuffer(null, 0, 0); if (recycle) { context.Recycle(tmp); } int msgCount; bool keepReading = state.ProcessBufferedData(context, out msgCount); if (msgCount > 0) { Interlocked.Add(ref totalMessages, msgCount); } if (!state.CanRead) { // allows eager shutdown of reads if (state.IncomingBufferedLength != 0) { throw new InvalidOperationException("Extra data discovered on an outbound-only socket"); } keepReading = false; } if (keepReading) { if (state.IncomingBufferedLength == 0) { // use a fraction of a buffer until we think there is something useful to read SetMicroBuffer(args); } else { // we know we're expecting more, since we have some buffered that we can't yet handle SetFullBuffer(args); } try { if (state.CanRead && !state.Socket.ReceiveAsync(args)) { goto MoreToRead; } } catch (ObjectDisposedException) { // can get this if the client disconnects and the socket gets shut down Debug.WriteLine("EOF/close: " + state); CloseSocket(args); } } } else { Debug.WriteLine("EOF/close: " + state); CloseSocket(args); } } catch (CloseSocketException) { // fairly clean exit CloseSocket(args); } catch (Exception ex) { Console.Error.WriteLine("{0}\tReceive: {1}", Connection.GetIdent(args), ex.Message); CloseSocket(args); } }
public SocketUdpServer(ITestOutputHelper output, IPAddress address, bool dualMode, out int port) { _output = output; if (dualMode) { _server = new Socket(SocketType.Dgram, ProtocolType.Udp); } else { _server = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); } port = _server.BindToAnonymousPort(address); IPAddress remoteAddress = address.AddressFamily == AddressFamily.InterNetwork ? IPAddress.Any : IPAddress.IPv6Any; EndPoint remote = new IPEndPoint(remoteAddress, 0); SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.RemoteEndPoint = remote; e.SetBuffer(new byte[1], 0, 1); e.Completed += new EventHandler<SocketAsyncEventArgs>(Received); e.UserToken = _waitHandle; _server.ReceiveFromAsync(e); }
public void AcceptAsync_WithReceiveBuffer_Success() { Assert.True(Capability.IPv4Support()); AutoResetEvent accepted = new AutoResetEvent(false); using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { int port = server.BindToAnonymousPort(IPAddress.Loopback); server.Listen(1); const int acceptBufferOverheadSize = 288; // see https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.acceptasync(v=vs.110).aspx const int acceptBufferDataSize = 256; const int acceptBufferSize = acceptBufferOverheadSize + acceptBufferDataSize; byte[] sendBuffer = new byte[acceptBufferDataSize]; new Random().NextBytes(sendBuffer); SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs(); acceptArgs.Completed += OnAcceptCompleted; acceptArgs.UserToken = accepted; acceptArgs.SetBuffer(new byte[acceptBufferSize], 0, acceptBufferSize); Assert.True(server.AcceptAsync(acceptArgs)); _log.WriteLine("IPv4 Server: Waiting for clients."); using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { client.Connect(IPAddress.Loopback, port); client.Send(sendBuffer); client.Shutdown(SocketShutdown.Both); } Assert.True( accepted.WaitOne(Configuration.PassingTestTimeout), "Test completed in alotted time"); Assert.Equal( SocketError.Success, acceptArgs.SocketError); Assert.Equal( acceptBufferDataSize, acceptArgs.BytesTransferred); Assert.Equal( new ArraySegment<byte>(sendBuffer), new ArraySegment<byte>(acceptArgs.Buffer, 0, acceptArgs.BytesTransferred)); } }
// "The parameter remoteEP must not be of type DnsEndPoint." public void Socket_ReceiveMessageFromAsyncDnsEndPoint_Throws() { using (Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp)) { int port = socket.BindToAnonymousPort(IPAddress.IPv6Loopback); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new DnsEndPoint("localhost", port, AddressFamily.InterNetworkV6); args.SetBuffer(new byte[1], 0, 1); Assert.Throws<ArgumentException>(() => { socket.ReceiveMessageFromAsync(args); }); } }
private void SendCompleted(SocketAsyncEventArgs args) { try { ProcessMore: var conn = (Connection)args.UserToken; if (args.BytesTransferred != 0 && args.SocketError == SocketError.Success) { if (conn != null) { conn.Seen(); // update LastSeen } Interlocked.Add(ref totalBytesSent, args.BytesTransferred); #if DEBUG && LOG_OUTBOUND conn.LogOutput(args.Buffer, args.Offset, args.BytesTransferred); #endif var state = (Connection)args.UserToken; if (args.BytesTransferred == args.Count) { int toWrite = state.ReadOutgoing(context, args.Buffer, 0, args.Buffer.Length); if (toWrite > 0) { args.SetBuffer(args.Buffer, 0, toWrite); if (!state.Socket.SendAsync(args)) { goto ProcessMore; } } else { OnFlushed(conn); context.Recycle(args); } } else { // more to be sent from that buffer args.SetBuffer(args.Buffer, args.Offset + args.BytesTransferred, args.Count - args.BytesTransferred); if (!state.Socket.SendAsync(args)) { goto ProcessMore; } } } else { Console.Error.WriteLine("{0}\tSocket closed: {1}", Connection.GetIdent(args), args.SocketError); CloseSocket(args); } } catch (ObjectDisposedException) { CloseSocket(args); } catch (Exception ex) { Console.Error.WriteLine("{0}\tSend: {1}", Connection.GetIdent(args), ex.Message); CloseSocket(args); } }
private void asyncWrite(SocketAsyncEventArgs writeEvent) { writeEvent.SetBuffer(0, ((AsyncUserToken)writeEvent.UserToken).length); m_connectionServer.SendAsync(writeEvent); }
private static void AsyncTcpSendCallback(object sender, SocketAsyncEventArgs e) { StreamProcessor streamProcessor = (StreamProcessor)e.UserToken; BaseClient client = streamProcessor.m_client; try { Queue tcpQueue = streamProcessor.m_tcpQueue; if (tcpQueue != null && client.Socket.Connected) { int bytesTransferred = e.BytesTransferred; byte[] tcpSendBuffer = streamProcessor.m_tcpSendBuffer; int num = 0; if (bytesTransferred != e.Count) { if (streamProcessor.m_sendBufferLength > bytesTransferred) { num = streamProcessor.m_sendBufferLength - bytesTransferred; Array.Copy(tcpSendBuffer, bytesTransferred, tcpSendBuffer, 0, num); } } e.SetBuffer(0, 0); int num2 = streamProcessor.m_firstPkgOffset; object syncRoot; Monitor.Enter(syncRoot = tcpQueue.SyncRoot); try { if (tcpQueue.Count > 0) { do { PacketIn packetIn = (PacketIn)tcpQueue.Peek(); byte[] array = null; int num3; if (client.Encryted) { array = StreamProcessor.cloneArrary(client.SEND_KEY, 8); num3 = packetIn.CopyTo(tcpSendBuffer, num, num2, ref array); } else { num3 = packetIn.CopyTo(tcpSendBuffer, num, num2); } num2 += num3; num += num3; if (packetIn.Length <= num2) { if (array != null && array != client.SEND_KEY) { client.SEND_KEY = StreamProcessor.cloneArrary(array, 8); } tcpQueue.Dequeue(); num2 = 0; if (client.Encryted) { streamProcessor.send_fsm.UpdateState(); packetIn.isSended = true; } } if (tcpSendBuffer.Length == num) { break; } }while (tcpQueue.Count > 0); } streamProcessor.m_firstPkgOffset = num2; if (num <= 0) { streamProcessor.m_sendingTcp = false; return; } } finally { Monitor.Exit(syncRoot); } streamProcessor.m_sendBufferLength = num; e.SetBuffer(0, num); if (!client.SendAsync(e)) { StreamProcessor.AsyncTcpSendCallback(sender, e); } } } catch (Exception ex) { StreamProcessor.log.Error("AsyncTcpSendCallback", ex); StreamProcessor.log.WarnFormat("It seems <{0}> went linkdead. Closing connection. (SendTCP, {1}: {2})", client, ex.GetType(), ex.Message); client.Disconnect(); } }
private IObservable <byte> CreateReceiveObservable() { Logger.LogTrace("Creating Observable."); var buffer = new byte[ReceiveBufferSize]; int position = 0; var semaphore = new SemaphoreSlim(0, 1); void handler(object sender, SocketAsyncEventArgs a) => semaphore.Release(); var args = new SocketAsyncEventArgs(); args.Completed += handler; args.SetBuffer(buffer, 0, buffer.Length); return(Observable.Create <byte>(observer => { Cts = new CancellationTokenSource(); NewThreadScheduler.Default.Schedule(() => { Logger.LogTrace("Starting Receive."); try { while (!Cts !.IsCancellationRequested) { if (position < args.BytesTransferred) { observer.OnNext(buffer[position++]); continue; } position = 0; if (Socket.ReceiveAsync(args)) { semaphore.Wait(Cts.Token); } Logger.LogTrace($"Received {args.BytesTransferred} bytes."); if (args.BytesTransferred == 0) { break; } } observer.OnCompleted(); } catch (Exception e) { Logger.LogTrace("Receive Ended."); // crashes logger if (!Cts !.IsCancellationRequested && !Disposer.DisposeRequested) { Logger.LogWarning(e, "Read Socket Exception."); } observer.OnCompleted(); } }); return Disposable.Create(() => { Logger.LogCritical("cancelling"); Cts?.Cancel(); }); })); }
static void Main(string[] args) { #if NETCOREAPP2_0 Console.WriteLine(RuntimeInformation.OSArchitecture.ToString()); Console.WriteLine(RuntimeInformation.OSDescription); Console.WriteLine(RuntimeInformation.FrameworkDescription); #endif Console.Title = "Client"; int port = 18180; Console.WriteLine("Please input port to connect ..."); if ( int.TryParse ( Console.ReadLine() , out int p ) ) { port = p; } Console.WriteLine($"Connect Port: {port}"); IPAddress ipa; IPAddress.TryParse("127.0.0.1", out ipa); var socket = new Socket ( AddressFamily.InterNetwork , SocketType.Stream , ProtocolType.Tcp ); var ipep = new IPEndPoint(ipa, port); socket.Connect(ipep); //Console.ReadLine(); var handler = new SocketAsyncDataHandler <string> ( socket , 1 ); var sendEncoding = Encoding.UTF8; var receiveEncoding = Encoding.UTF8; handler .StartReceiveWholeDataPackets ( 4 , 0 , 4 , () => { var saea = new SocketAsyncEventArgs(); saea.SetBuffer ( new byte[64 * 1024] , 0 , 64 * 1024 ); return(saea); } , (x, y, z) => { var s = receiveEncoding.GetString(y); //Console.WriteLine("SocketID: {1}{0}Length: {2}{0}Data: {2}", "\r\n", x.SocketID, y.Length ,s); Console.Write(s); return(true); } ); string input = string.Empty; while ((input = Console.ReadLine()) != "q") { try { var buffer = sendEncoding.GetBytes(input); var l = buffer.Length; byte[] intBytes = BytesHelper.GetLengthHeaderBytes(buffer); handler.SendDataSync(intBytes); handler.SendDataSync(buffer); } catch (Exception e) { Console.WriteLine(e.ToString()); } } }
void ProcessReceive(Socket readingSock, SocketAsyncEventArgs e) { var userToken = (ClientSocketState)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { if (!userToken.ReadHeader) { // if we've filled the buffer we can decode the header if (e.Offset + e.BytesTransferred == userToken.Header.Length) { userToken.ReadHeader = true; userToken.MessageLength = BitConverter.ToUInt32(userToken.Header, 4); userToken.CompleteMessage = new byte[userToken.MessageLength]; for (int i = 0; i < userToken.Header.Length; i++) { userToken.CompleteMessage[i] = userToken.Header[i]; } e.SetBuffer(userToken.CompleteMessage, userToken.Header.Length, userToken.CompleteMessage.Length - userToken.Header.Length); if (!readingSock.ReceiveAsync(e)) { ProcessReceive(readingSock, e); } } else { if (!readingSock.ReceiveAsync(e)) { ProcessReceive(readingSock, e); } } } else { if (e.Offset + e.BytesTransferred == userToken.MessageLength) { // copy buffer var fullPacket = userToken.CompleteMessage; // reset state userToken.ReadHeader = false; userToken.MessageLength = 0; // process the message ThreadPool.QueueUserWorkItem(delegate { ProcessPacket(fullPacket, readingSock, userToken); }); // start listening for more packets e.SetBuffer(userToken.Header, 0, userToken.Header.Length); if (!readingSock.ReceiveAsync(e)) { ProcessReceive(readingSock, e); } } else { if (!readingSock.ReceiveAsync(e)) { ProcessReceive(readingSock, e); } } } } else { // socket disconnected ClientDisconnected(readingSock); } }
/// <summary> /// Try to send pending data /// </summary> protected override void TrySend() { if (sending) { return; } if (!IsConnected) { return; } Boolean process = true; while (process) { process = false; lock (sendLock) { if (sending) { return; } // Swap send buffers if (sendBuffer.IsEmpty) { // Swap flush and main buffers sendBuffer = Interlocked.Exchange(ref sendBufferMain, sendBuffer); sendBufferFlushOffset = 0; // Update statistic BytesPending = 0; BytesSending += sendBuffer.Size; sending = !sendBuffer.IsEmpty; } else { return; } } // Check if the flush buffer is empty if (sendBuffer.IsEmpty) { // Call the empty send buffer handler OnEmpty(); return; } try { // Async write with the write handler _sendEventArg.SetBuffer(sendBuffer.Data, (Int32)sendBufferFlushOffset, (Int32)(sendBuffer.Size - sendBufferFlushOffset)); if (!Socket.SendAsync(_sendEventArg)) { process = ProcessSend(_sendEventArg); } } catch (ObjectDisposedException) { } } }
static void Networking() { Console.WriteLine("Nätverk - Skapar two sockets och skriver 1.000.000 gånger."); Console.ReadKey(); using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) using (Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { listener.Bind(new IPEndPoint(IPAddress.Loopback, 0)); listener.Listen(1); Task connectTask = Task.Run(() => client.Connect(listener.LocalEndPoint)); using (Socket server = listener.Accept()) { connectTask.Wait(); using (var clientAre = new AutoResetEvent(false)) using (var clientSaea = new SocketAsyncEventArgs()) using (var serverAre = new AutoResetEvent(false)) using (var serverSaea = new SocketAsyncEventArgs()) { byte[] sendBuffer = new byte[1000]; clientSaea.SetBuffer(sendBuffer, 0, sendBuffer.Length); clientSaea.Completed += delegate { clientAre.Set(); }; byte[] receiveBuffer = new byte[1000]; serverSaea.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); serverSaea.Completed += delegate { serverAre.Set(); }; var sw = new Stopwatch(); int gen0 = GC.CollectionCount(0), gen1 = GC.CollectionCount(1), gen2 = GC.CollectionCount(2); sw.Start(); for (int i = 0; i < 1_000_000; i++) { if (client.SendAsync(clientSaea)) { clientAre.WaitOne(); } if (clientSaea.SocketError != SocketError.Success) { throw new SocketException((int)clientSaea.SocketError); } if (server.ReceiveAsync(serverSaea)) { serverAre.WaitOne(); } if (serverSaea.SocketError != SocketError.Success) { throw new SocketException((int)clientSaea.SocketError); } } Console.WriteLine($"Elapsed={sw.Elapsed} Gen0={GC.CollectionCount(0) - gen0} Gen1={GC.CollectionCount(1) - gen1} Gen2={GC.CollectionCount(2) - gen2}"); } } } Console.WriteLine(); Console.ReadKey(); }
void SetFullBuffer(SocketAsyncEventArgs args) { var buffer = context.GetBuffer(); args.SetBuffer(buffer, 0, buffer.Length); }
/// <summary> /// Try to send pending data /// </summary> private void TrySend() { if (!IsConnected) { return; } bool empty = false; bool process = true; while (process) { process = false; lock (_sendLock) { // Is previous socket send in progress? if (_sendBufferFlush.IsEmpty) { // Swap flush and main buffers _sendBufferFlush = Interlocked.Exchange(ref _sendBufferMain, _sendBufferFlush); _sendBufferFlushOffset = 0; // Update statistic BytesPending = 0; BytesSending += _sendBufferFlush.Size; // Check if the flush buffer is empty if (_sendBufferFlush.IsEmpty) { // Need to call empty send buffer handler empty = true; // End sending process _sending = false; } } else { return; } } // Call the empty send buffer handler if (empty) { OnEmpty(); return; } try { // Async write with the write handler _sendEventArg.SetBuffer(_sendBufferFlush.Data, (int)_sendBufferFlushOffset, (int)(_sendBufferFlush.Size - _sendBufferFlushOffset)); if (!Socket.SendAsync(_sendEventArg)) { process = ProcessSend(_sendEventArg); } } catch (ObjectDisposedException) { } } }
/// returns null if the caller should redo from start; returns /// a non-null result to preocess the data private async Task <ArraySegment <byte> > ReceiveInitialDataUnknownStrategyAsync(SocketAsyncEventArgs args) { // to prove that it works OK, we need (after a read): // - have seen return 0 and Available > 0 // - have reen return <= 0 and Available == 0 and is true EOF // // if we've seen both, we can switch to the simpler approach; // until then, if we just see return 0 and Available > 0, well... // we're happy // // note: if we see return 0 and available == 0 and not EOF, // then we know that zero-length receive is not supported try { args.SetBuffer(_zeroLengthBuffer, 0, 0); // we'll do a receive and see what happens await Socket.ReceiveSignalAsync(args); } catch { // well, it didn't like that... switch to small buffers _bufferStyle = BufferStyle.UseSmallBuffer; return(default(ArraySegment <byte>)); } if (args.SocketError != SocketError.Success) { // let the calling code explode return(new ArraySegment <byte>(_zeroLengthBuffer)); } if (Socket.Available > 0) { _seenReceiveZeroWithAvailable = true; if (_seenReceiveZeroWithEOF) { _bufferStyle = BufferStyle.UseZeroLengthBuffer; } // we'll let the calling method pull the data out return(new ArraySegment <byte>(_zeroLengthBuffer)); } // so now we need to detect if this is a genuine EOF; if it isn't, // that isn't conclusive, because could just be timing; but if it is: great var buffer = LeaseSmallBuffer(); try { args.SetBuffer(buffer.Array, buffer.Offset, buffer.Count); // we'll do a receive and see what happens await Socket.ReceiveSignalAsync(args); if (args.SocketError != SocketError.Success) { // we can't actually conclude anything RecycleSmallBuffer(ref buffer); throw new SocketException((int)args.SocketError); } if (args.BytesTransferred <= 0) { RecycleSmallBuffer(ref buffer); _seenReceiveZeroWithEOF = true; if (_seenReceiveZeroWithAvailable) { _bufferStyle = BufferStyle.UseZeroLengthBuffer; } // we'll let the calling method shut everything down return(new ArraySegment <byte>(_zeroLengthBuffer)); } // otherwise, we got something that looked like an EOF from receive, // but which wasn't really; we'll have to do things the hard way :( _bufferStyle = BufferStyle.UseSmallBuffer; return(buffer); } catch { // already recycled (or not) correctly in the success cases RecycleSmallBuffer(ref buffer); throw; } }
//It is said that ReceiveAsync/SendAsync never returns false unless error //So...let's just treat it as always true private void ReceiveCompleted(object sender, SocketAsyncEventArgs e) { try { if (!skt.Connected) { parent.Disconnect(); return; } if (e.SocketError != SocketError.Success) { throw new SocketException((int)e.SocketError); } switch (receiveState) { case ReceiveState.ReceivingHdr: if (e.BytesTransferred < 5) { parent.Disconnect(); return; } if (e.Buffer[0] == 0x4d && e.Buffer[1] == 0x61 && e.Buffer[2] == 0x64 && e.Buffer[3] == 0x65 && e.Buffer[4] == 0xff) { log.InfoFormat("Usage request from: @ {0}.", skt.RemoteEndPoint); byte[] c = Encoding.ASCII.GetBytes(parent.Manager.MaxClients + ":" + parent.Manager.Clients.Count.ToString()); skt.Send(c); return; } if (e.Buffer[0] == 0x3c && e.Buffer[1] == 0x70 && e.Buffer[2] == 0x6f && e.Buffer[3] == 0x6c && e.Buffer[4] == 0x69) { ProcessPolicyFile(); return; } int len = (e.UserToken as ReceiveToken).Length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(e.Buffer, 0)) - 5; if (len < 0 || len > BUFFER_SIZE) { throw new InternalBufferOverflowException(); } Packet packet = null; try { packet = Packet.Packets[(PacketID)e.Buffer[4]].CreateInstance(); } catch { log.ErrorFormat("Packet ID not found: {0}", e.Buffer[4]); } (e.UserToken as ReceiveToken).Packet = packet; receiveState = ReceiveState.ReceivingBody; e.SetBuffer(0, len); skt.ReceiveAsync(e); break; case ReceiveState.ReceivingBody: if (e.BytesTransferred < (e.UserToken as ReceiveToken).Length) { parent.Disconnect(); return; } Packet pkt = (e.UserToken as ReceiveToken).Packet; pkt.Read(parent, e.Buffer, 0, (e.UserToken as ReceiveToken).Length); receiveState = ReceiveState.Processing; bool cont = OnPacketReceived(pkt); if (cont && skt.Connected) { receiveState = ReceiveState.ReceivingHdr; e.SetBuffer(0, 5); skt.ReceiveAsync(e); } break; default: throw new InvalidOperationException(e.LastOperation.ToString()); } } catch (Exception ex) { OnError(ex); } }
public void ReceiveMessageFromAsync_NotSupported() { using (Socket sock = new Socket(SocketType.Dgram, ProtocolType.Udp)) { byte[] buf = new byte[1]; EndPoint ep = new IPEndPoint(IPAddress.Any, 0); sock.Bind(ep); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.SetBuffer(buf, 0, buf.Length); args.RemoteEndPoint = ep; Assert.Throws<PlatformNotSupportedException>(() => sock.ReceiveMessageFromAsync(args)); } }
/// <summary> /// 设置SocketAsyncEventArgs缓存区 /// </summary> /// <param name="arg">SocketAsyncEventArgs对象</param> public static void SetBuffer(SocketAsyncEventArgs arg) { var buffer = BufferManager.GetBuffer(); arg.SetBuffer(buffer.Buffer, buffer.Offset, buffer.Count); }
public SocketUdpServer(ITestOutputHelper output, IPAddress address, bool dualMode, out int port) { _output = output; if (dualMode) { _server = new Socket(SocketType.Dgram, ProtocolType.Udp); } else { _server = new Socket(address.AddressFamily, SocketType.Dgram, ProtocolType.Udp); } port = _server.BindToAnonymousPort(address); SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.SetBuffer(new byte[1], 0, 1); e.Completed += new EventHandler<SocketAsyncEventArgs>(Received); e.UserToken = _waitHandle; _server.ReceiveAsync(e); }
private void ProcessReceive(SocketAsyncEventArgs e) { if (isShuttingDown) { return; } if (e.SocketError == SocketError.Success) { #if DEBUG_NETWORK string debugData = "Received " + e.BytesTransferred + " byte. "; #endif if (e.BytesTransferred == 4) { state.ExpectedReceiveBytes = BitConverter.ToInt32(state.PreReceiveBuffer, 0); int bufferSize = ByteHelper.RoundToPowerOfTwo(state.ExpectedReceiveBytes); if (bufferSize > recvBufferSize) { bool change = false; if (bufferSize > MAX_BUFFER_SIZE) { if (recvBufferSize != MAX_BUFFER_SIZE) { recvBufferSize = MAX_BUFFER_SIZE; change = true; } } else { recvBufferSize = bufferSize; change = true; } if (change) { recvSocket.ReceiveBufferSize = recvBufferSize; state.ReceiveBuffer = new byte[recvBufferSize]; } } #if USE_VARIABLE_BUFFER_SIZE recvSocket.ReceiveBufferSize = recvBufferSize; #endif int receivingBytes = (state.ExpectedReceiveBytes > recvBufferSize) ? recvBufferSize : state.ExpectedReceiveBytes; e.SetBuffer(state.ReceiveBuffer, 0, receivingBytes); #if DEBUG_NETWORK debugData += "Expected receiving bytes: " + receivingBytes + ". "; Log.Write(debugData); #endif try { recvSocket.ReceiveAsync(e); } catch (Exception) { } } else { if (e.BytesTransferred == 10) { string msg = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred); if (msg.Equals("@Shutdown@")) { recvSocket.Shutdown(SocketShutdown.Receive); recvSocket.Close(); sendSocket.Shutdown(SocketShutdown.Send); sendSocket.Close(); isConnected = false; if (ServerDisconnected != null) { ServerDisconnected(); } return; } } while (copyingRecvBuffer) { } #if DEBUG_NETWORK debugData += "Actual received data: "; for (int i = 0; i < e.BytesTransferred; ++i) { debugData += e.Buffer[i] + " "; } Log.Write(debugData); #endif receivingData = true; int newOffset = state.Offset + e.BytesTransferred; if (newOffset > state.ReceivedData.Length) { byte[] tmp = new byte[state.Offset]; Buffer.BlockCopy(state.ReceivedData, 0, tmp, 0, state.Offset); int newLength = ByteHelper.RoundToPowerOfTwo(newOffset); state.ReceivedData = new byte[newLength]; Buffer.BlockCopy(tmp, 0, state.ReceivedData, 0, state.Offset); } Buffer.BlockCopy(e.Buffer, 0, state.ReceivedData, state.Offset, e.BytesTransferred); state.Offset += e.BytesTransferred; receivingData = false; if (state.Offset >= state.ExpectedReceiveBytes) { state.Offset = 0; receivedDataList.Add(ByteHelper.Truncate(state.ReceivedData, 0, state.ExpectedReceiveBytes)); #if USE_VARIABLE_BUFFER_SIZE recvSocket.ReceiveBufferSize = 4; #endif state.ExpectedReceiveBytes = 4; e.SetBuffer(state.PreReceiveBuffer, 0, 4); #if DEBUG_NETWORK Log.Write("Waiting to receive data length"); #endif try { recvSocket.ReceiveAsync(e); } catch (Exception) { } } else { int receivingBytes = state.ExpectedReceiveBytes - state.Offset; if (receivingBytes > recvBufferSize) { receivingBytes = recvBufferSize; } e.SetBuffer(state.ReceiveBuffer, 0, receivingBytes); #if DEBUG_NETWORK debugData += "Expected receiving bytes: " + receivingBytes + ". "; Log.Write(debugData); #endif try { recvSocket.ReceiveAsync(e); } catch (Exception) { } } } } else { Log.Write("Failed to receive: " + e.SocketError.ToString()); } }
/// <summary> /// This method is invoked when an asynchronous receive operation completes. /// If the remote host closed the connection, then the socket is closed. /// If data was received then the data is echoed back to the client. /// </summary> /// <param name="e"></param> private void ProcessReceive(SocketAsyncEventArgs e) { try { // check if the remote host closed the connection var token = ((HttpListenUserToken)e.UserToken); Logger.Warning(string.Format("IP:{0} SocketError:{1} BufOffsize:{2} BufCount:{3} Transfer:{4}", e.RemoteEndPoint, e.SocketError, e.Offset, e.Count, e.BytesTransferred)); if (e.SocketError == SocketError.Success) { #region 数据接收处理 if (e.BytesTransferred > 0) { if (token.Data == null) { token.Data = new byte[_maxPageSize]; } int count = Math.Min(_maxPageSize - token.DataLength, e.BytesTransferred); Buffer.BlockCopy(e.Buffer, e.Offset, token.Data, token.DataLength, count); token.DataLength += count; } #endregion //if (hasFinished) //{ #region 数据发送 //解析数据 string recContent = token.Data != null ? _encoding.GetString(token.Data, 0, token.DataLength) : string.Empty; HttpListenContext context = null; if (token.DataLength > 0) { context = new HttpListenContext(recContent); //把收到的文件夹解析成thhp包头,内容竺信息 } string data; if (context != null && context.IsValidContext && (context.HttpMethod == "GET" || context.HttpMethod == "POST")) { try { data = SuccessResponse(ProcessContext(context)); //ProcessContext得到要发送至设备的数据,并且发送给设备 } catch (Exception exception) { data = SuccessResponse(ToJsonMessage(exception.Message)); Logger.Error(exception, "HttpListen Error"); } } else if (context == null) { data = SuccessResponse(ToJsonMessage("无效数据!")); Logger.Error("HttpListenContext不能为空"); } else { Logger.Error("HttpListenContext无效"); data = SuccessResponse(ToJsonMessage("无效数据!")); } var buf = _encoding.GetBytes(data); token.IsReset = true; _mBufferManager.FreeBuffer(e); e.SetBuffer(buf, 0, buf.Length); // read the next block of data send from the client bool willRaiseEvent = token.ClientSocket.SendAsync(e); if (!willRaiseEvent) { ProcessSend(e); } #endregion //} } } catch (Exception ex) { Logger.Log(LogLevel.Error, ex.StackTrace.ToString(), ex); CloseClientSocket(e); } finally { if (e.SocketError == SocketError.SocketError) { CloseClientSocket(e); } } }
// This method is invoked when an asynchronous receive operation completes. // If the remote host closed the connection, then the socket is closed. // If data was received then the data is echoed back to the client. private void ProcessReceive(SocketAsyncEventArgs e) { _log.WriteLine( this.GetHashCode() + " ProcessReceive(bytesTransferred={0}, SocketError={1}, _numConnectedSockets={2})", e.BytesTransferred, e.SocketError, _numConnectedSockets); // Check if the remote host closed the connection. AsyncUserToken token = (AsyncUserToken)e.UserToken; if (e.BytesTransferred > 0 && e.SocketError == SocketError.Success) { // Increment the count of the total bytes receive by the server. Interlocked.Add(ref _totalBytesRead, e.BytesTransferred); _log.WriteLine(this.GetHashCode() + " The server has read a total of {0} bytes", _totalBytesRead); // Echo the data received back to the client. e.SetBuffer(e.Offset, e.BytesTransferred); bool willRaiseEvent = token.Socket.SendAsync(e); if (!willRaiseEvent) { ProcessSend(e); } } else { CloseClientSocket(e); } }
private void SocketReceiveArgs_Completed(object sender, SocketAsyncEventArgs receiveArgs) { //while (isok) //{ if (receiveArgs.SocketError == SocketError.Success) { //System.Threading.Thread.Sleep(100); //received = Encoding.UTF8.GetString(receiveArgs.Buffer, receiveArgs.Offset, receiveArgs.BytesTransferred); try { labered: int bytesRead = receiveArgs.BytesTransferred; if (bytesRead > 0) { byte[] tempbtye = new byte[bytesRead]; Array.Copy(receiveArgs.Buffer, tempbtye, tempbtye.Length); // receiveArgs.Dispose(); if (tempb != null) { byte[] tempbtyes = new byte[tempbtye.Length + tempb.Length]; Array.Copy(tempb, tempbtyes, tempb.Length); Array.Copy(tempbtye, 0, tempbtyes, tempb.Length, tempbtye.Length); tempbtye = tempbtyes; } labe881: if (tempbtye[0] == 0x99) { timeout = DateTime.Now; if (bytesRead > 1) { byte[] b = new byte[bytesRead - 1]; byte[] t = tempbtye; Array.Copy(t, 1, b, 0, b.Length); tempbtye = b; bytesRead = bytesRead - (1); goto labe881; } else { done.Set(); return; } // continue; } int a = tempbtye[1]; String temp = System.Text.Encoding.UTF8.GetString(tempbtye, 2, a); int len = int.Parse(temp); if (len > tempbtye.Length) { tempb = new byte[tempbtye.Length]; Array.Copy(tempbtye, tempb, tempbtye.Length); // goto labered; int lennext = 5120; if ((len - tempbtye.Length) < 5120) { lennext = len - tempbtye.Length + 2 + a; } System.Threading.Tasks.Task.Delay(100); socketReceiveArgs = new SocketAsyncEventArgs(); socketReceiveArgs.SetBuffer(new byte[lennext], 0, lennext); socketReceiveArgs.Completed += SocketReceiveArgs_Completed; tcpc.ReceiveAsync(socketReceiveArgs); return; } //int b = netc.Buffer[2 + a+1]; //temp = System.Text.ASCIIEncoding.ASCII.GetString(netc.Buffer, 2 + a + 1, b); //len = int.Parse(temp); temp = System.Text.Encoding.UTF8.GetString(tempbtye, 2 + a, len); tempb = null; try { if (tempbtye[0] == 0xff) { if (temp.IndexOf("token") >= 0) { Tokan = temp.Split('|')[1]; } } else if (receiveServerEvent != null) { receiveServerEvent(tempbtye[0], temp); } } catch (Exception e) { if (ErrorMge != null) { ErrorMge(1, e.Message); } } if (bytesRead > (2 + a + len)) { byte[] b = new byte[bytesRead - (2 + a + len)]; byte[] t = tempbtye; Array.Copy(t, (2 + a + len), b, 0, b.Length); tempbtye = b; bytesRead = bytesRead - (2 + a + len); goto labe881; } timeout = DateTime.Now; } else { TimeSpan ts = DateTime.Now - timeout; if (ts.Seconds > mytimeout) { Isline = false; //stop(); //isreceives = false; timeoutevent(); //return; } } } catch (Exception e) { if (ErrorMge != null) { ErrorMge(1, e.Message); } } finally { done.Set(); } } //} }
// Removes the buffer from a SocketAsyncEventArg object. // This frees the buffer back to the buffer pool. public void FreeBuffer(SocketAsyncEventArgs args) { _freeIndexPool.Push(args.Offset); args.SetBuffer(null, 0, 0); }
public void AcceptAsync_WithReceiveBuffer_Failure() { // // Unix platforms don't yet support receiving data with AcceptAsync. // Assert.True(Capability.IPv4Support()); using (Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) { int port = server.BindToAnonymousPort(IPAddress.Loopback); server.Listen(1); SocketAsyncEventArgs acceptArgs = new SocketAsyncEventArgs(); acceptArgs.Completed += OnAcceptCompleted; acceptArgs.UserToken = new ManualResetEvent(false); byte[] buffer = new byte[1024]; acceptArgs.SetBuffer(buffer, 0, buffer.Length); Assert.Throws<PlatformNotSupportedException>(() => server.AcceptAsync(acceptArgs)); } }
protected override void ProcessReceive(SocketAsyncEventArgs e) { if (!ValidateAsyncResult(e)) { return; } var context = (ConnectContext)e.UserToken; int prevMatched = context.SearchState.Matched; int result = e.Buffer.SearchMark(e.Offset, e.BytesTransferred, context.SearchState); if (result < 0) { int total = e.Offset + e.BytesTransferred; if (total >= m_ReceiveBufferSize) { OnException("receive buffer size has been exceeded"); return; } e.SetBuffer(total, m_ReceiveBufferSize - total); StartReceive(context.Socket, e); return; } int responseLength = (prevMatched > 0 && result == e.Offset) ? (e.Offset - prevMatched) : result; if (e.Offset + e.BytesTransferred > responseLength + m_LineSeparator.Length) { OnException("protocol error: more data has been received"); return; } var lineReader = new StringReader(ASCIIEncoding.GetString(e.Buffer, 0, responseLength)); var line = lineReader.ReadLine(); if (string.IsNullOrEmpty(line)) { OnException("protocol error: invalid response"); return; } //HTTP/1.1 2** OK var pos = line.IndexOf(m_Space); if (pos <= 0 || line.Length <= (pos + 2)) { OnException("protocol error: invalid response"); return; } var httpProtocol = line.Substring(0, pos); if (!httpProtocol.StartsWith(m_ResponsePrefix)) { OnException("protocol error: invalid protocol"); return; } var statusPos = line.IndexOf(m_Space, pos + 1); if (statusPos < 0) { OnException("protocol error: invalid response"); return; } int statusCode; //Status code should be 2** if (!int.TryParse(line.Substring(pos + 1, statusPos - pos - 1), out statusCode) || (statusCode > 299 || statusCode < 200)) { OnException("the proxy server refused the connection"); return; } OnCompleted(new ProxyEventArgs(context.Socket, TargetHostHame)); }
/// <summary> /// Called whenever socket operation completes /// </summary> /// <param name="index"></param> /// <param name="arg"></param> /// <param name="ok"></param> /// <param name="timeout"></param> /// <returns>true if completed, false to be called again</returns> public bool CompleteAsync(int index, SocketAsyncEventArgs arg, out bool ok, out int timeout) { ok = false; timeout = _timeout; if (arg.SocketError != SocketError.Success) { _logger.Debug("Probe {index} : {remoteEp} found no opc server. {error}", index, _socket?.RemoteEndPoint, arg.SocketError); _state = State.BeginProbe; return(true); } while (true) { switch (_state) { case State.BeginProbe: if (arg.ConnectSocket == null) { _logger.Error("Probe {index} : Called without connected socket!", index); return(true); } _socket = arg.ConnectSocket; var ep = _socket.RemoteEndPoint.TryResolve(); using (var ostrm = new MemoryStream(_buffer, 0, _buffer.Length)) using (var encoder = new BinaryEncoder(ostrm, ServiceMessageContext.GlobalContext)) { encoder.WriteUInt32(null, TcpMessageType.Hello); encoder.WriteUInt32(null, 0); encoder.WriteUInt32(null, 0); // ProtocolVersion encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize); encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize); encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize); encoder.WriteUInt32(null, TcpMessageLimits.DefaultMaxMessageSize); encoder.WriteByteString(null, Encoding.UTF8.GetBytes("opc.tcp://" + ep)); _size = encoder.Close(); } _buffer[4] = (byte)(_size & 0x000000FF); _buffer[5] = (byte)((_size & 0x0000FF00) >> 8); _buffer[6] = (byte)((_size & 0x00FF0000) >> 16); _buffer[7] = (byte)((_size & 0xFF000000) >> 24); arg.SetBuffer(_buffer, 0, _size); _len = 0; _logger.Debug("Probe {index} : {ep} ({remoteEp})...", index, "opc.tcp://" + ep, _socket.RemoteEndPoint); _state = State.SendHello; if (!_socket.SendAsync(arg)) { break; } return(false); case State.SendHello: _len += arg.Count; if (_len >= _size) { _len = 0; _size = TcpMessageLimits.MessageTypeAndSize; _state = State.ReceiveSize; arg.SetBuffer(0, _size); // Start read size if (!_socket.ReceiveAsync(arg)) { break; } return(false); } // Continue to send reset arg.SetBuffer(_len, _size - _len); if (!_socket.SendAsync(arg)) { break; } return(false); case State.ReceiveSize: _len += arg.Count; if (_len >= _size) { var type = BitConverter.ToUInt32(_buffer, 0); if (type != TcpMessageType.Acknowledge) { if (TcpMessageType.IsValid(type)) { _logger.Debug("Probe {index} : {remoteEp} " + "returned message type {type} != Ack.", index, _socket.RemoteEndPoint, type); } else { _logger.Verbose("Probe {index} : {remoteEp} " + "returned invalid message type {type}.", index, _socket.RemoteEndPoint, type); } _state = State.BeginProbe; return(true); } _size = (int)BitConverter.ToUInt32(_buffer, 4); if (_size > _buffer.Length) { _logger.Debug("Probe {index} : {remoteEp} " + "returned invalid message length {size}.", index, _socket.RemoteEndPoint, _size); _state = State.BeginProbe; return(true); } _len = 0; // Start receive message _state = State.ReceiveAck; } // Continue to read rest of type and size arg.SetBuffer(_len, _size - _len); if (!_socket.ReceiveAsync(arg)) { break; } return(false); case State.ReceiveAck: _len += arg.Count; if (_len >= _size) { _state = State.BeginProbe; // Validate message using (var istrm = new MemoryStream(_buffer, 0, _size)) using (var decoder = new BinaryDecoder(istrm, ServiceMessageContext.GlobalContext)) { var protocolVersion = decoder.ReadUInt32(null); var sendBufferSize = (int)decoder.ReadUInt32(null); var receiveBufferSize = (int)decoder.ReadUInt32(null); var maxMessageSize = (int)decoder.ReadUInt32(null); var maxChunkCount = (int)decoder.ReadUInt32(null); _logger.Information("Probe {index} : found OPC UA " + "server at {remoteEp} (protocol:{protocolVersion}) ...", index, _socket.RemoteEndPoint, protocolVersion); if (sendBufferSize < TcpMessageLimits.MinBufferSize || receiveBufferSize < TcpMessageLimits.MinBufferSize) { _logger.Warning("Probe {index} : Bad size value read " + "{sendBufferSize} or {receiveBufferSize} from opc " + "server at {_socket.RemoteEndPoint}.", index, sendBufferSize, receiveBufferSize, _socket.RemoteEndPoint); } } ok = true; return(true); } // Continue to read rest arg.SetBuffer(_len, _size - _len); if (!_socket.ReceiveAsync(arg)) { break; } return(false); default: throw new SystemException("Bad state"); } } }
public void Socket_SendToAsyncV4IPEndPointToV4Host_Throws() { Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp); socket.DualMode = false; SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort); args.SetBuffer(new byte[1], 0, 1); bool async = socket.SendToAsync(args); Assert.False(async); Assert.Equal(SocketError.Fault, args.SocketError); }
private void sArgs_Completed(object sender, SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { var buffer = (byte[])e.Buffer; var sArgs = new SocketAsyncEventArgs(); sArgs.RemoteEndPoint = e.RemoteEndPoint; sArgs.SetBuffer(buffer, 0, buffer.Length); sArgs.Completed += (o, a) => { if (a.SocketError == SocketError.Success) { var timeData = a.Buffer; ConvertBufferToCurrentTime(buffer); } }; _Socket.ReceiveAsync(sArgs); } }
[Fact] // Base case public void Socket_SendToAsyncV4IPEndPointToV4Host_Throws() { Socket socket = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort); args.SetBuffer(new byte[1], 0, 1); bool async = socket.SendToAsync(args); Assert.False(async); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Assert.Equal(SocketError.Fault, args.SocketError); } else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) { // NOTE: on Linux, this API returns ENETUNREACH instead of EFAULT: this platform // checks the family of the provided socket address before checking its size // (as long as the socket address is large enough to store an address family). Assert.Equal(SocketError.NetworkUnreachable, args.SocketError); } else { // NOTE: on other Unix platforms, this API returns EINVAL instead of EFAULT. Assert.Equal(SocketError.InvalidArgument, args.SocketError); } }
public static int ReadPartial(Socket socket, byte[] buffer, int offset, int size, TimeSpan timeout) { #if FEATURE_SOCKET_SYNC socket.ReceiveTimeout = (int)timeout.TotalMilliseconds; try { return(socket.Receive(buffer, offset, size, SocketFlags.None)); } catch (SocketException ex) { if (ex.SocketErrorCode == SocketError.TimedOut) { throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture, "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds)); } throw; } #elif FEATURE_SOCKET_EAP var receiveCompleted = new ManualResetEvent(false); var sendReceiveToken = new PartialSendReceiveToken(socket, receiveCompleted); var args = new SocketAsyncEventArgs { RemoteEndPoint = socket.RemoteEndPoint, UserToken = sendReceiveToken }; args.Completed += ReceiveCompleted; args.SetBuffer(buffer, offset, size); try { if (socket.ReceiveAsync(args)) { if (!receiveCompleted.WaitOne(timeout)) { throw new SshOperationTimeoutException( string.Format( CultureInfo.InvariantCulture, "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds)); } } if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } return(args.BytesTransferred); } finally { // initialize token to avoid the waithandle getting used after it's disposed args.UserToken = null; args.Dispose(); receiveCompleted.Dispose(); } #else #error Receiving data from a Socket is not implemented. #endif }
private async void ReceiveFromSocketAndPushToWriterAsync() { SocketAsyncEventArgs args = null; try { // if the consumer says they don't want the data, we need to shut down the receive GC.KeepAlive(_input.Writing.ContinueWith(delegate {// GC.KeepAlive here just to shut the compiler up try { Socket.Shutdown(SocketShutdown.Receive); } catch { } })); // wait for someone to be interested in data before we // start allocating buffers and probing the socket await _input.ReadingStarted; args = GetOrCreateSocketAsyncEventArgs(); while (!_input.Writing.IsCompleted) { bool haveWriteBuffer = false; WritableBuffer buffer = default(WritableBuffer); var initialSegment = default(ArraySegment <byte>); try { int bytesFromInitialDataBuffer = 0; if (Socket.Available == 0) { // now, this gets a bit messy unfortunately, because support for the ideal option // (zero-length reads) is platform dependent switch (_bufferStyle) { case BufferStyle.Unknown: try { initialSegment = await ReceiveInitialDataUnknownStrategyAsync(args); } catch { initialSegment = default(ArraySegment <byte>); } if (initialSegment.Array == null) { continue; // redo from start } break; case BufferStyle.UseZeroLengthBuffer: // if we already have a buffer, use that (but: zero count); otherwise use a shared // zero-length; this avoids constantly changing the buffer that the args use, which // avoids some overheads args.SetBuffer(args.Buffer ?? _zeroLengthBuffer, 0, 0); // await async for the io work to be completed await Socket.ReceiveSignalAsync(args); break; case BufferStyle.UseSmallBuffer: // We need to do a speculative receive with a *cheap* buffer while we wait for input; it would be *nice* if // we could do a zero-length receive, but this is not supported equally on all platforms (fine on Windows, but // linux hates it). The key aim here is to make sure that we don't tie up an entire block from the memory pool // waiting for input on a socket; fine for 1 socket, not so fine for 100,000 sockets // do a short receive while we wait (async) for data initialSegment = LeaseSmallBuffer(); args.SetBuffer(initialSegment.Array, initialSegment.Offset, initialSegment.Count); // await async for the io work to be completed await Socket.ReceiveSignalAsync(args); break; } if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } // note we can't check BytesTransferred <= 0, as we always // expect 0; but if we returned, we expect data to be // buffered *on the socket*, else EOF if ((bytesFromInitialDataBuffer = args.BytesTransferred) <= 0) { if (ReferenceEquals(initialSegment.Array, _zeroLengthBuffer)) { // sentinel value that means we should just // consume sync (we expect there to be data) initialSegment = default(ArraySegment <byte>); } else { // socket reported EOF RecycleSmallBuffer(ref initialSegment); } if (Socket.Available == 0) { // yup, definitely an EOF break; } } } // note that we will try to coalesce things here to reduce the number of flushes; we // certainly want to coalesce the initial buffer (from the speculative receive) with the initial // data, but we probably don't want to buffer indefinitely; for now, it will buffer up to 4 pages // before flushing (entirely arbitrarily) - might want to make this configurable later buffer = _input.Alloc(SmallBufferSize * 2); haveWriteBuffer = true; const int FlushInputEveryBytes = 4 * MemoryPool.MaxPooledBlockLength; if (initialSegment.Array != null) { // need to account for anything that we got in the speculative receive if (bytesFromInitialDataBuffer != 0) { buffer.Write(new Span <byte>(initialSegment.Array, initialSegment.Offset, bytesFromInitialDataBuffer)); } // make the small buffer available to other consumers RecycleSmallBuffer(ref initialSegment); } bool isEOF = false; while (Socket.Available != 0 && buffer.BytesWritten < FlushInputEveryBytes) { buffer.Ensure(); // ask for *something*, then use whatever is available (usually much much more) SetBuffer(buffer.Memory, args); // await async for the io work to be completed await Socket.ReceiveSignalAsync(args); // either way, need to validate if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } int len = args.BytesTransferred; if (len <= 0) { // socket reported EOF isEOF = true; break; } // record what data we filled into the buffer buffer.Advance(len); } if (isEOF) { break; } } finally { RecycleSmallBuffer(ref initialSegment); if (haveWriteBuffer) { await buffer.FlushAsync(); } } } _input.CompleteWriter(); } catch (Exception ex) { // don't trust signal after an error; someone else could // still have it and invoke Set if (args != null) { args.UserToken = null; } _input?.CompleteWriter(ex); } finally { RecycleSocketAsyncEventArgs(args); } }
// Assigns a buffer from the buffer pool to the // specified SocketAsyncEventArgs object. // // <returns>true if the buffer was successfully set, else false</returns> public bool SetBuffer(SocketAsyncEventArgs args) { if (_freeIndexPool.Count > 0) { args.SetBuffer(_buffer, _freeIndexPool.Pop(), _bufferSize); } else { if ((_numBytes - _bufferSize) < _currentIndex) { return false; } args.SetBuffer(_buffer, _currentIndex, _bufferSize); _currentIndex += _bufferSize; } return true; }
public static void ReadContinuous(Socket socket, byte[] buffer, int offset, int size, Action <byte[], int, int> processReceivedBytesAction) { #if FEATURE_SOCKET_SYNC // do not time-out receive socket.ReceiveTimeout = 0; while (socket.Connected) { try { var bytesRead = socket.Receive(buffer, offset, size, SocketFlags.None); if (bytesRead == 0) { break; } processReceivedBytesAction(buffer, offset, bytesRead); } catch (SocketException ex) { if (IsErrorResumable(ex.SocketErrorCode)) { continue; } switch (ex.SocketErrorCode) { case SocketError.ConnectionAborted: case SocketError.ConnectionReset: // connection was closed return; case SocketError.Interrupted: // connection was closed because FIN/ACK was not received in time after // shutting down the (send part of the) socket return; default: throw; // throw any other error } } } #elif FEATURE_SOCKET_EAP var completionWaitHandle = new ManualResetEvent(false); var readToken = new ContinuousReceiveToken(socket, processReceivedBytesAction, completionWaitHandle); var args = new SocketAsyncEventArgs { RemoteEndPoint = socket.RemoteEndPoint, UserToken = readToken }; args.Completed += ReceiveCompleted; args.SetBuffer(buffer, offset, size); if (!socket.ReceiveAsync(args)) { ReceiveCompleted(null, args); } completionWaitHandle.WaitOne(); completionWaitHandle.Dispose(); if (readToken.Exception != null) { throw readToken.Exception; } #else #error Receiving data from a Socket is not implemented. #endif }
//发出异步写入 protected void asyncWrite(SocketAsyncEventArgs writeEvent) { writeEvent.SetBuffer(0, ((AsyncUserToken)writeEvent.UserToken).length); m_mySocket.SendAsync(writeEvent); }
/// <summary> /// Receives data from a bound <see cref="Socket"/>into a receive buffer. /// </summary> /// <param name="socket"></param> /// <param name="buffer">An array of type <see cref="byte"/> that is the storage location for the received data. </param> /// <param name="offset">The position in <paramref name="buffer"/> parameter to store the received data.</param> /// <param name="size">The number of bytes to receive.</param> /// <param name="timeout">Specifies the amount of time after which the call will time out.</param> /// <returns> /// The number of bytes received. /// </returns> /// <remarks> /// If no data is available for reading, the <see cref="Read(Socket,byte[], int, int, TimeSpan)"/> method will /// block until data is available or the time-out value was exceeded. If the time-out value was exceeded, the /// <see cref="Read(Socket,byte[], int, int, TimeSpan)"/> call will throw a <see cref="SshOperationTimeoutException"/>. /// If you are in non-blocking mode, and there is no data available in the in the protocol stack buffer, the /// <see cref="Read(Socket,byte[], int, int, TimeSpan)"/> method will complete immediately and throw a <see cref="SocketException"/>. /// </remarks> public static int Read(Socket socket, byte[] buffer, int offset, int size, TimeSpan timeout) { #if FEATURE_SOCKET_SYNC var totalBytesRead = 0; var totalBytesToRead = size; socket.ReceiveTimeout = (int)timeout.TotalMilliseconds; do { try { var bytesRead = socket.Receive(buffer, offset + totalBytesRead, totalBytesToRead - totalBytesRead, SocketFlags.None); if (bytesRead == 0) { return(0); } totalBytesRead += bytesRead; } catch (SocketException ex) { if (IsErrorResumable(ex.SocketErrorCode)) { ThreadAbstraction.Sleep(30); continue; } if (ex.SocketErrorCode == SocketError.TimedOut) { throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture, "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds)); } throw; } }while (totalBytesRead < totalBytesToRead); return(totalBytesRead); #elif FEATURE_SOCKET_EAP var receiveCompleted = new ManualResetEvent(false); var sendReceiveToken = new BlockingSendReceiveToken(socket, buffer, offset, size, receiveCompleted); var args = new SocketAsyncEventArgs { UserToken = sendReceiveToken, RemoteEndPoint = socket.RemoteEndPoint }; args.Completed += ReceiveCompleted; args.SetBuffer(buffer, offset, size); try { if (socket.ReceiveAsync(args)) { if (!receiveCompleted.WaitOne(timeout)) { throw new SshOperationTimeoutException(string.Format(CultureInfo.InvariantCulture, "Socket read operation has timed out after {0:F0} milliseconds.", timeout.TotalMilliseconds)); } } if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } return(sendReceiveToken.TotalBytesTransferred); } finally { // initialize token to avoid the waithandle getting used after it's disposed args.UserToken = null; args.Dispose(); receiveCompleted.Dispose(); } #else #error Receiving data from a Socket is not implemented. #endif }
private void DualModeSendToAsync_IPEndPointToHost_Helper(IPAddress connectTo, IPAddress listenOn, bool dualModeServer) { int port; ManualResetEvent waitHandle = new ManualResetEvent(false); Socket client = new Socket(SocketType.Dgram, ProtocolType.Udp); using (SocketUdpServer server = new SocketUdpServer(listenOn, dualModeServer, out port)) { SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(connectTo, port); args.SetBuffer(new byte[1], 0, 1); args.UserToken = waitHandle; args.Completed += AsyncCompleted; bool async = client.SendToAsync(args); if (async) { Assert.True(waitHandle.WaitOne(5000), "Timeout while waiting for connection"); } Assert.Equal(1, args.BytesTransferred); if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } bool success = server.WaitHandle.WaitOne(100); // Make sure the bytes were received if (!success) { throw new TimeoutException(); } } }
public static void Send(Socket socket, byte[] data, int offset, int size) { #if FEATURE_SOCKET_SYNC var totalBytesSent = 0; // how many bytes are already sent var totalBytesToSend = size; do { try { var bytesSent = socket.Send(data, offset + totalBytesSent, totalBytesToSend - totalBytesSent, SocketFlags.None); if (bytesSent == 0) { throw new SshConnectionException("An established connection was aborted by the server.", DisconnectReason.ConnectionLost); } totalBytesSent += bytesSent; } catch (SocketException ex) { if (IsErrorResumable(ex.SocketErrorCode)) { // socket buffer is probably full, wait and try again ThreadAbstraction.Sleep(30); } else { throw; // any serious error occurr } } } while (totalBytesSent < totalBytesToSend); #elif FEATURE_SOCKET_EAP var sendCompleted = new ManualResetEvent(false); var sendReceiveToken = new BlockingSendReceiveToken(socket, data, offset, size, sendCompleted); var socketAsyncSendArgs = new SocketAsyncEventArgs { RemoteEndPoint = socket.RemoteEndPoint, UserToken = sendReceiveToken }; socketAsyncSendArgs.SetBuffer(data, offset, size); socketAsyncSendArgs.Completed += SendCompleted; try { if (socket.SendAsync(socketAsyncSendArgs)) { if (!sendCompleted.WaitOne()) { throw new SocketException((int)SocketError.TimedOut); } } if (socketAsyncSendArgs.SocketError != SocketError.Success) { throw new SocketException((int)socketAsyncSendArgs.SocketError); } if (sendReceiveToken.TotalBytesTransferred == 0) { throw new SshConnectionException("An established connection was aborted by the server.", DisconnectReason.ConnectionLost); } } finally { // initialize token to avoid the completion waithandle getting used after it's disposed socketAsyncSendArgs.UserToken = null; socketAsyncSendArgs.Dispose(); sendCompleted.Dispose(); } #else #error Sending data to a Socket is not implemented. #endif }
protected override void DoSend(byte[] bytes, int offset, int length, AsyncContinuation asyncContinuation) { lock (this) { var args = new SocketAsyncEventArgs(); args.SetBuffer(bytes, offset, length); args.UserToken = asyncContinuation; args.Completed += this.SocketOperationCompleted; args.RemoteEndPoint = this.endpoint; if (!this.socket.SendToAsync(args)) { this.SocketOperationCompleted(this.socket, args); } } }
/// <summary> /// Removes the buffer from a SocketAsyncEventArg object. /// This frees the buffer back to the buffer pool. /// </summary> /// <param name="args">SocketAsyncEventArgs where is the buffer to be removed.</param> internal void FreeBuffer(SocketAsyncEventArgs args) { this.freeIndexPool.Push(args.Offset); args.SetBuffer(null, 0, 0); }
[Fact] // Base case // "The parameter remoteEP must not be of type DnsEndPoint." public void Socket_SendToAsyncDnsEndPoint_Throws() { Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new DnsEndPoint("localhost", UnusedPort); args.SetBuffer(new byte[1], 0, 1); Assert.Throws<ArgumentException>(() => { socket.SendToAsync(args); }); }
// Removes the buffer from a SocketAsyncEventArg object. // This frees the buffer back to the buffer pool public void FreeBuffer(SocketAsyncEventArgs args) { m_freeIndexPool.Push(args.Offset); args.SetBuffer(null, 0, 0); }
private void ReceiveFromAsync_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false) { using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp)) { int port = serverSocket.BindToAnonymousPort(listenOn); ManualResetEvent waitHandle = new ManualResetEvent(false); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(listenOn, port); args.SetBuffer(new byte[1], 0, 1); args.UserToken = waitHandle; args.Completed += AsyncCompleted; bool async = serverSocket.ReceiveFromAsync(args); SocketUdpClient client = new SocketUdpClient(_log, serverSocket, connectTo, port); if (async && !waitHandle.WaitOne(expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout)) { throw new TimeoutException(); } if (args.SocketError != SocketError.Success) { throw new SocketException((int)args.SocketError); } Assert.Equal(1, args.BytesTransferred); Assert.Equal<Type>(args.RemoteEndPoint.GetType(), typeof(IPEndPoint)); IPEndPoint remoteEndPoint = args.RemoteEndPoint as IPEndPoint; Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily); Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address); } }
/// <summary> /// Close the socket associated with the client. /// </summary> /// <param name="e">SocketAsyncEventArg associated with the completed send/receive operation.</param> private void CloseClientSocket(SocketAsyncEventArgs e) { AsyncUserToken aut = e.UserToken as AsyncUserToken; TMSKSocket s = null; try { s = aut.CurrentSocket; string ip = "未知"; try { ip = string.Format("{0}", s.RemoteEndPoint); } catch (System.Exception) { } LogManager.WriteLog(LogTypes.Error, string.Format("远程连接关闭: {0}, 当前总共: {1}", ip, ConnectedSocketsCount)); CloseSocket(s); } finally { aut.CurrentSocket = null; //释放 aut.Tag = null; //释放 // Free the SocketAsyncEventArg so they can be reused by another client. if (e.LastOperation == SocketAsyncOperation.Send) { e.SetBuffer(null, 0, 0); //回收内存 if (GameManager.FlagOptimizeThreadPool3) { //TMSKThreadStaticClass.GetInstance().PushReadSocketAsyncEventArgs(e); if (null != s) { s.PushWriteSocketAsyncEventArgs(e); } } else { this.writePool.Push(e); } } else if (e.LastOperation == SocketAsyncOperation.Receive) { if (GameManager.FlagOptimizeThreadPool3) { //TMSKThreadStaticClass.GetInstance().PushReadSocketAsyncEventArgs(e); if (null != s) { s.PushReadSocketAsyncEventArgs(e); } } else { this.readPool.Push(e); } } } }
[Fact] // Base case // "The supplied EndPoint of AddressFamily InterNetwork is not valid for this Socket, use InterNetworkV6 instead." public void Socket_ReceiveMessageFromAsyncV4IPEndPointFromV4Client_Throws() { Socket socket = new Socket(SocketType.Dgram, ProtocolType.Udp); socket.DualMode = false; SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(IPAddress.Loopback, UnusedPort); args.SetBuffer(new byte[1], 0, 1); Assert.Throws<ArgumentException>(() => { socket.ReceiveMessageFromAsync(args); }); }
private void Socket_Completed(object sender, SocketAsyncEventArgs e) { try { switch (e.LastOperation) { case SocketAsyncOperation.ReceiveFrom: if (e.SocketError != SocketError.Success) { if (e.SocketError != SocketError.OperationAborted) { logger.LogError($"Socket Receive error: {e.SocketError}."); } return; } Task.Run(async() => { var ctx = (SocketRecvContext)e.UserToken; var remotep = e.RemoteEndPoint as IPEndPoint; //logger.LogTrace($"ReceiveFrom {remotep.Port} local port {ctx.So.LocalEndPoint}"); var bmore = await ctx.Callback(ctx.Buffer, e.BytesTransferred, remotep).ConfigureAwait(false); if (bmore) { ReceivMore(ctx, e); } }); break; case SocketAsyncOperation.SendTo: var ctx = (SocketSendContext)e.UserToken; if (e.SocketError != SocketError.Success) { logger.LogError($"Socket Send error {e.SocketError}. From {ctx.So.LocalEndPoint} to {e.RemoteEndPoint}."); } if (ctx != null) { --ctx.RepeatCount; } //logger.LogInformation($"Socket Send error {e.RemoteEndPoint} {ctx.So.LocalEndPoint}"); if (ctx.RepeatCount > 0) { Task.Run(async() => { await Task.Delay(ctx.RepeatDelay).ConfigureAwait(false); e.SetBuffer(ctx.Data, ctx.Offset, ctx.Count); ctx.So.SendToAsync(e); }); } else { var err = e.SocketError; StoreSocketAsyncEventArgs(e); ctx.ErrorCallback?.Invoke(err); } break; case SocketAsyncOperation.Disconnect: break; default: break; } return; } catch (Exception exception) { logger.LogError(exception, "Exception in UdpMulticastServer."); } }
private void ReceiveMessageFromAsync_Helper(IPAddress listenOn, IPAddress connectTo, bool expectedToTimeout = false) { using (Socket serverSocket = new Socket(SocketType.Dgram, ProtocolType.Udp)) { serverSocket.ReceiveTimeout = expectedToTimeout ? Configuration.FailingTestTimeout : Configuration.PassingTestTimeout; int port = serverSocket.BindToAnonymousPort(listenOn); ManualResetEvent waitHandle = new ManualResetEvent(false); SocketAsyncEventArgs args = new SocketAsyncEventArgs(); args.RemoteEndPoint = new IPEndPoint(connectTo, port); args.SetBuffer(new byte[1], 0, 1); args.Completed += AsyncCompleted; args.UserToken = waitHandle; bool async = serverSocket.ReceiveMessageFromAsync(args); Assert.True(async); SocketUdpClient client = new SocketUdpClient(_log, serverSocket, connectTo, port); if (!waitHandle.WaitOne(serverSocket.ReceiveTimeout)) { throw new TimeoutException(); } Assert.Equal(1, args.BytesTransferred); Assert.Equal<Type>(args.RemoteEndPoint.GetType(), typeof(IPEndPoint)); IPEndPoint remoteEndPoint = args.RemoteEndPoint as IPEndPoint; Assert.Equal(AddressFamily.InterNetworkV6, remoteEndPoint.AddressFamily); Assert.Equal(connectTo.MapToIPv6(), remoteEndPoint.Address); Assert.Equal(SocketFlags.None, args.SocketFlags); Assert.NotNull(args.ReceiveMessageFromPacketInfo); Assert.Equal(connectTo, args.ReceiveMessageFromPacketInfo.Address); // TODO: Move to NetworkInformation tests. // Assert.Equal(NetworkInterface.IPv6LoopbackInterfaceIndex, args.ReceiveMessageFromPacketInfo.Interface); } }
//-------------------------------------------// /// <summary> /// Start sending data to the socket. Make sure slimLock is entered in read mode before calling this, /// and that disposing is not true. Ensure an error handler is implemented which forwards to ProcessError. /// </summary> private void StartSend() { if (_disposing) { _sendLock.Release(); return; } byte[] buffer = BufferCache.Get(); // iterate while there are more bytes to be sent for (;;) { // get data without removing it from the buffer and set buffer on socket int count; _sendBuffer.Take(); if (_currentCallbackAction == null) { count = _sendBuffer.Item.Dequeue(buffer, 0, Global.BufferSizeLocal); if (count == 0) { _sendLock.Release(); // more data to send? yes, take the lock and return positive if (_sendBuffer.Item.Length > 0 && _sendLock.TryTake) { count = _sendBuffer.Item.Dequeue(buffer, 0, Global.BufferSizeLocal); } else { _sendBuffer.Release(); BufferCache.Set(buffer); return; } } } else { _callbackLock.Take(); count = _sendBuffer.Item.Dequeue(buffer, 0, Global.BufferSizeLocal); if (count == 0) { _sendLock.Release(); // more data to send? yes, take the lock and return positive if (_sendBuffer.Item.Length > 0 && _sendLock.TryTake) { count = _sendBuffer.Item.Dequeue(buffer, 0, Global.BufferSizeLocal); } else { _sendBuffer.Release(); _callbackLock.Release(); BufferCache.Set(buffer); return; } } _currentCallbackIndex -= count; _callbackLock.Release(); } _sendBuffer.Release(); _sendSocketArgs.SetBuffer(buffer, 0, count); if (_disposing) { _sendLock.Release(); return; } if (Socket.Connected) { // sendAsync returns true if the I/O operation is pending. An event will be raised upon completion. // returns false if the I/O operation completed synchronously if (Socket.SendAsync(_sendSocketArgs)) { // an event is going to be raised to OnIOComplete_Send, so let's exit right now because we're done return; } // send -- is there more data to send now? no, break iteration if (!CompleteSend(_sendSocketArgs)) { return; } } else { _sendLock.Release(); BufferCache.Set(buffer); if (_disposing) { return; } ProcessError("Socket was disconnected mid-send."); return; } } // in case loop is ever broken //_syncLock.ExitReadLock(); }
private void ClientSend(object state) { try { Socket socket = new Socket(_connectTo.AddressFamily, SocketType.Dgram, ProtocolType.Udp); for (int i = 0; i < Configuration.UDPRedundancy; i++) { SocketAsyncEventArgs e = new SocketAsyncEventArgs(); e.RemoteEndPoint = new IPEndPoint(_connectTo, _port); e.SetBuffer(new byte[1], 0, 1); socket.SendToAsync(e); } } catch (SocketException) { _serverSocket.Dispose(); // Cancels the test } }
/// <summary> /// Receive data from the server using the established socket connection /// </summary> /// <returns>The data received from the server</returns> public void Receive() { string response = "Operation Timeout"; // We are receiving over an established socket connection if (_socket != null) { // Create SocketAsyncEventArgs context object SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs(); socketEventArg.RemoteEndPoint = _socket.RemoteEndPoint; // Setup the buffer to receive the data socketEventArg.SetBuffer(new Byte[MAX_BUFFER_SIZE], 0, MAX_BUFFER_SIZE); // Inline event handler for the Completed event. // Note: This even handler was implemented inline in order to make // this method self-contained. socketEventArg.Completed += new EventHandler <SocketAsyncEventArgs>(delegate(object s, SocketAsyncEventArgs e) { if (e.SocketError == SocketError.Success) { // Retrieve the data from the buffer response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred); response = response.Replace("\0", ""); try { // Parse the string for an x, y offset and rotation data int firstOpenParenthesis = response.IndexOf('('); int firstCommaAfterParenthesis = response.Substring(firstOpenParenthesis).IndexOf(',') + firstOpenParenthesis; int firstClosedParenthesis = response.Substring(firstCommaAfterParenthesis).IndexOf(')') + firstCommaAfterParenthesis; int firstSemicolon = response.Substring(firstClosedParenthesis).IndexOf(';') + firstClosedParenthesis; int firstPound = response.Substring(firstSemicolon).IndexOf('#') + firstSemicolon; string x_str = response.Substring(firstOpenParenthesis + 1, firstCommaAfterParenthesis - firstOpenParenthesis - 1); string y_str = response.Substring(firstCommaAfterParenthesis + 1, firstClosedParenthesis - firstCommaAfterParenthesis - 1); string rotation_str = response.Substring(firstSemicolon + 1, firstPound - firstSemicolon - 1); float temp_x = float.Parse(x_str, CultureInfo.InvariantCulture); float temp_y = float.Parse(y_str, CultureInfo.InvariantCulture); if (temp_x < 0.999f) { ir_x = translateWeightingFactor * float.Parse(x_str, CultureInfo.InvariantCulture) + (1 - translateWeightingFactor) * ir_x; } if (temp_y < 1.332f) { ir_y = translateWeightingFactor * float.Parse(y_str, CultureInfo.InvariantCulture) + (1 - translateWeightingFactor) * ir_y; } if (!rotation_str.Contains("NaN")) { // Update existing change to rotation float newRotation = float.Parse(rotation_str, CultureInfo.InvariantCulture); deltaRotation = newRotation - oldRotation; oldRotation = newRotation; } } catch (ArgumentOutOfRangeException) { Debug.Log("Lost IR Data"); } } else { response = "Error";// e.SocketError.ToString(); } _clientDone.Set(); }); Send("ACK"); // Unblock the server mutex // Sets the state of the event to nonsignaled, causing threads to block _clientDone.Reset(); // Make an asynchronous Receive request over the socket _socket.ReceiveAsync(socketEventArg); // Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds. // If no response comes back within this time then proceed _clientDone.WaitOne(TIMEOUT_MILLISECONDS); } }