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 }
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 }
/// <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 }
/// <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 }