public override SocketAddress Serialize() { SocketAddress sockaddr = null; switch (address.AddressFamily) { case AddressFamily.InterNetwork: // .net produces a 16 byte buffer, even though // only 8 bytes are used. I guess its just a // holdover from struct sockaddr padding. sockaddr = new SocketAddress(AddressFamily.InterNetwork, 16); // bytes 2 and 3 store the port, the rest // stores the address sockaddr[2] = (byte)((port >> 8) & 0xff); sockaddr[3] = (byte)(port & 0xff); long addr = address.InternalIPv4Address; sockaddr[4] = (byte)(addr & 0xff); sockaddr[5] = (byte)((addr >> 8) & 0xff); sockaddr[6] = (byte)((addr >> 16) & 0xff); sockaddr[7] = (byte)((addr >> 24) & 0xff); break; case AddressFamily.InterNetworkV6: sockaddr = new SocketAddress(AddressFamily.InterNetworkV6, 28); sockaddr[2] = (byte)((port >> 8) & 0xff); sockaddr[3] = (byte)(port & 0xff); byte[] addressBytes = address.GetAddressBytes(); for (int i = 0; i < 16; i++) sockaddr[8 + i] = addressBytes[i]; sockaddr[24] = (byte)(address.ScopeId & 0xff); sockaddr[25] = (byte)((address.ScopeId >> 8) & 0xff); sockaddr[26] = (byte)((address.ScopeId >> 16) & 0xff); sockaddr[27] = (byte)((address.ScopeId >> 24) & 0xff); break; } return (sockaddr); }
// bytes 2 and 3 store the port, the rest // stores the address public override EndPoint Create(SocketAddress socketAddress) { if (socketAddress == null) throw new ArgumentNullException("socketAddress"); if (socketAddress.Family != AddressFamily) throw new ArgumentException("The IPEndPoint was created using " + AddressFamily + " AddressFamily but SocketAddress contains " + socketAddress.Family + " instead, please use the same type."); SocketAddress sockaddr = socketAddress; int size = sockaddr.Size; AddressFamily family = sockaddr.Family; int port; IPEndPoint ipe = null; switch (family) { case AddressFamily.InterNetwork: if (size < 8) { return (null); } port = (((int)sockaddr[2]) << 8) + (int)sockaddr[3]; long address = (((long)sockaddr[7]) << 24) + (((long)sockaddr[6]) << 16) + (((long)sockaddr[5]) << 8) + (long)sockaddr[4]; ipe = new IPEndPoint(address, port); break; case AddressFamily.InterNetworkV6: if (size < 28) { return (null); } port = (((int)sockaddr[2]) << 8) + (int)sockaddr[3]; /// maybe flowid ? /* int unknown = (int)sockaddr[4] + (((int)sockaddr[5])<<8) + (((int)sockaddr[6])<<16) + (((int)sockaddr[7])<<24); */ int scopeId = (int)sockaddr[24] + (((int)sockaddr[25]) << 8) + (((int)sockaddr[26]) << 16) + (((int)sockaddr[27]) << 24); ushort[] addressData = new ushort[8]; for (int i = 0; i < 8; i++) addressData[i] = (ushort)((sockaddr[8 + i * 2] << 8) + sockaddr[8 + i * 2 + 1]); ipe = new IPEndPoint(new IPAddress(addressData, scopeId), port); break; default: return null; } return (ipe); }
public virtual EndPoint Create(SocketAddress socketAddress) { throw NotImplemented(); }