using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Net.Sockets; using System.Threading; using System.Net; using System.Runtime.InteropServices; using System.IO; using pb = Google.Protobuf; /// /// socket 辅助类 /// public static class SocketUtils { #region Socket /// /// socket辅助方法 /// /// /// public static void SetKeepAlive(this Socket sock, int interval_ms) { uint dummy = 0; byte[] inOptionValues = new byte[Marshal.SizeOf(dummy) * 3]; BitConverter.GetBytes((uint)1).CopyTo(inOptionValues, 0); BitConverter.GetBytes((uint)interval_ms).CopyTo(inOptionValues, Marshal.SizeOf(dummy)); BitConverter.GetBytes((uint)interval_ms).CopyTo(inOptionValues, Marshal.SizeOf(dummy) * 2); sock.IOControl(IOControlCode.KeepAliveValues, inOptionValues, null); } public static bool IsWriteAble(this Socket socket) { try { if (socket.Poll(-1, SelectMode.SelectWrite)) { return true; } } catch (SocketException se) { System.Diagnostics.Debug.WriteLine(se.Message); return false; } return false; } public static bool IsReadAble(this Socket socket) { try { if (socket.Poll(-1, SelectMode.SelectRead)) { return true; } } catch (SocketException se) { System.Diagnostics.Debug.WriteLine(se.Message); return false; } return false; } #endregion /// /// Task辅助方法 /// /// /// /// public static async Task WaitAsync(this Task task, TimeSpan timeout) { using (var timeoutCancellationTokenSource = new CancellationTokenSource()) { var delayTask = Task.Delay(timeout, timeoutCancellationTokenSource.Token); if (await Task.WhenAny(task, delayTask) == task) { timeoutCancellationTokenSource.Cancel(); return; } throw new TimeoutException("The operation has timed out."); } } /// /// ProtoBuf序列化 /// /// /// public static byte[] ToBytes(this pb::IMessage data) { using var ms = new MemoryStream(); using var os = new pb::CodedOutputStream(ms); data.WriteTo(os); os.Flush(); ms.Seek(0, SeekOrigin.Begin); return ms.ToArray(); } }