218 lines
5.7 KiB
C#
218 lines
5.7 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace UdtSharp
|
|
{
|
|
public class Channel
|
|
{
|
|
AddressFamily m_iIPversion; // IP version
|
|
|
|
Socket m_socket; // socket descriptor
|
|
|
|
int m_iSndBufSize; // UDP sending buffer size
|
|
int m_iRcvBufSize;
|
|
|
|
public Channel()
|
|
{
|
|
m_iIPversion = AddressFamily.InterNetwork;
|
|
m_iSndBufSize = 65536;
|
|
m_iRcvBufSize = 65536;
|
|
}
|
|
|
|
public Channel(AddressFamily addressFamily)
|
|
{
|
|
m_iIPversion = addressFamily;
|
|
m_iSndBufSize = 65536;
|
|
m_iRcvBufSize = 65536;
|
|
}
|
|
|
|
public void open(IPEndPoint addr)
|
|
{
|
|
// construct a socket
|
|
try
|
|
{
|
|
m_socket = new Socket(m_iIPversion, SocketType.Dgram, ProtocolType.Udp);
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
throw new UdtException(1, 0, e.ErrorCode);
|
|
}
|
|
|
|
if (null != addr)
|
|
{
|
|
try
|
|
{
|
|
m_socket.Bind(addr);
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
throw new UdtException(1, 3, e.ErrorCode);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
try
|
|
{
|
|
m_socket.Bind(new IPEndPoint(IPAddress.Any, 0));
|
|
}
|
|
catch (SocketException e)
|
|
{
|
|
throw new UdtException(1, 3, e.ErrorCode);
|
|
}
|
|
}
|
|
|
|
setUDPSockOpt();
|
|
}
|
|
|
|
public void open(Socket udpsock)
|
|
{
|
|
m_socket = udpsock;
|
|
setUDPSockOpt();
|
|
}
|
|
|
|
void setUDPSockOpt()
|
|
{
|
|
m_socket.ReceiveBufferSize = m_iRcvBufSize;
|
|
m_socket.SendBufferSize = m_iSndBufSize;
|
|
}
|
|
|
|
public void close()
|
|
{
|
|
m_socket.Close();
|
|
}
|
|
|
|
int getSndBufSize()
|
|
{
|
|
m_iSndBufSize = (int)m_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendBuffer);
|
|
return m_iSndBufSize;
|
|
}
|
|
|
|
int getRcvBufSize()
|
|
{
|
|
m_iRcvBufSize = (int)m_socket.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveBuffer);
|
|
return m_iRcvBufSize;
|
|
}
|
|
|
|
public void setSndBufSize(int size)
|
|
{
|
|
m_iSndBufSize = size;
|
|
}
|
|
|
|
public void setRcvBufSize(int size)
|
|
{
|
|
m_iRcvBufSize = size;
|
|
}
|
|
|
|
public void getSockAddr(ref IPEndPoint addr)
|
|
{
|
|
addr = (IPEndPoint)m_socket.LocalEndPoint;
|
|
}
|
|
|
|
void getPeerAddr(ref IPEndPoint addr)
|
|
{
|
|
addr = (IPEndPoint)m_socket.RemoteEndPoint;
|
|
}
|
|
|
|
public int sendto(IPEndPoint addr, Packet packet)
|
|
{
|
|
TraceSend(addr, packet);
|
|
|
|
// convert control information into network order
|
|
packet.ConvertControlInfoToNetworkOrder();
|
|
|
|
// convert packet header into network order
|
|
packet.ConvertHeaderToNetworkOrder();
|
|
|
|
byte[] data = packet.GetBytes();
|
|
int res = m_socket.SendTo(data, addr);
|
|
|
|
// convert back into local host order
|
|
packet.ConvertHeaderToHostOrder();
|
|
packet.ConvertControlInfoToHostOrder();
|
|
|
|
return res;
|
|
}
|
|
|
|
void TraceSend(IPEndPoint destination, Packet packet)
|
|
{
|
|
return;
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(DateTime.Now.ToString("hh:mm:ss.fff"));
|
|
sb.AppendFormat(" SND {0} => {1}", m_socket.LocalEndPoint, destination);
|
|
sb.AppendLine();
|
|
sb.AppendLine(packet.ToString());
|
|
sb.AppendLine();
|
|
Console.WriteLine(sb.ToString());
|
|
}
|
|
|
|
void TraceRecv(IPEndPoint source, Packet packet)
|
|
{
|
|
return;
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append(DateTime.Now.ToString("hh:mm:ss.fff"));
|
|
sb.AppendFormat(" RCV {0} <= {1}", m_socket.LocalEndPoint, source);
|
|
sb.AppendLine();
|
|
sb.AppendLine(packet.ToString());
|
|
sb.AppendLine();
|
|
Console.WriteLine(sb.ToString());
|
|
}
|
|
|
|
public int recvfrom(ref IPEndPoint addr, Packet packet)
|
|
{
|
|
try
|
|
{
|
|
if (!m_socket.Poll(10000, SelectMode.SelectRead))
|
|
return -1;
|
|
}
|
|
catch (SocketException sex)
|
|
{
|
|
return -1;
|
|
}
|
|
catch (ObjectDisposedException odex)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
byte[] bytes = new byte[Packet.m_iPktHdrSize + packet.getLength()];
|
|
|
|
EndPoint source = addr;
|
|
|
|
int res;
|
|
try
|
|
{
|
|
res = m_socket.ReceiveFrom(bytes, ref source);
|
|
}
|
|
catch (SocketException sex)
|
|
{
|
|
return -1;
|
|
}
|
|
catch (ObjectDisposedException odex)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
addr = source as IPEndPoint;
|
|
|
|
if (res <= 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
bool success = packet.SetHeaderAndDataFromBytes(bytes, res);
|
|
if (!success)
|
|
return -1;
|
|
|
|
// convert back into local host order
|
|
packet.ConvertHeaderToHostOrder();
|
|
packet.ConvertControlInfoToHostOrder();
|
|
|
|
TraceRecv(addr, packet);
|
|
|
|
return packet.getLength();
|
|
}
|
|
}
|
|
}
|