Created
July 29, 2015 13:39
-
-
Save Aimeast/24ca4d55943e80af1a84 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Socket operations | |
protected IAsyncResult BeginSocketRead(int length, ApmCallback callback) | |
{ | |
return BeginSocketIO(new byte[length], callback, _socket.BeginReceive, _socket.EndReceive); | |
} | |
protected IAsyncResult BeginSocketWrite(byte[] data, ApmCallback callback) | |
{ | |
return BeginSocketIO(data, callback, _socket.BeginSend, _socket.EndSend); | |
} | |
private IAsyncResult BeginSocketIO(byte[] data, ApmCallback callback, BeginSocket begin, EndSocket end) | |
{ | |
var apm = new ApmStruct { Data = data, Callback = callback, Begin = begin, End = end }; | |
return begin(data, 0, data.Length, SocketFlags.None, ar => EndSocketIO(ar, end), apm); | |
} | |
private void EndSocketIO(IAsyncResult ar, EndSocket end) | |
{ | |
SocketError errorCode; | |
var length = end(ar, out errorCode); | |
var apm = (ApmStruct)ar.AsyncState; | |
apm.Callback?.Invoke(apm.Data, errorCode); | |
} | |
protected delegate IAsyncResult BeginSocket(byte[] buffer, int offset, int size, SocketFlags socketFlags, AsyncCallback callback, object state); | |
protected delegate int EndSocket(IAsyncResult ar, out SocketError err); | |
protected delegate void ApmCallback(byte[] data, SocketError err); | |
protected class ApmStruct | |
{ | |
public byte[] Data; | |
public ApmCallback Callback; | |
public BeginSocket Begin; | |
public EndSocket End; | |
} | |
#endregion | |
#region Socket operations | |
public byte[] SocketRead(int length) | |
{ | |
return SocketIO(new byte[length], _socket.Receive); | |
} | |
public void SocketWrite(byte[] data) | |
{ | |
SocketIO(data, _socket.Send); | |
} | |
private byte[] SocketIO(byte[] data, Func<byte[], int, int, SocketFlags, int> func) | |
{ | |
var pos = 0; | |
var length = data.Length; | |
while (pos < length) | |
{ | |
try | |
{ | |
pos += func(data, pos, length - pos, SocketFlags.None); | |
} | |
catch (SocketException ex) | |
{ | |
if (ex.SocketErrorCode == SocketError.WouldBlock | |
|| ex.SocketErrorCode == SocketError.IOPending | |
|| ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) | |
{ | |
Thread.Sleep(30); | |
} | |
else | |
throw; | |
} | |
} | |
return data; | |
} | |
#endregion | |
#region Socket operations | |
public async Task<byte[]> SocketRead(int length) | |
{ | |
var data = new byte[length]; | |
var len = await Task.Factory.FromAsync( | |
_socket.BeginReceive(data, 0, data.Length, SocketFlags.None, null, null), | |
ar => _socket.EndReceive(ar)); | |
return data; | |
} | |
public async Task SocketWrite(byte[] data) | |
{ | |
var len = await Task.Factory.FromAsync( | |
_socket.BeginSend(data, 0, data.Length, SocketFlags.None, null, null), | |
ar => _socket.EndSend(ar)); | |
} | |
#endregion |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment