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();
}
}