* Fixed a few lingering bugs with the CAPS event queue wanting to time out * Forced CapsRequest to always use POST * Removed more debugging spew from HttpBase git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@1346 52acb1d6-8a22-11de-b505-999d5b087335
159 lines
4.4 KiB
C#
159 lines
4.4 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
|
|
public class TCPPipe
|
|
{
|
|
protected class SocketPacket
|
|
{
|
|
public System.Net.Sockets.Socket TCPSocket;
|
|
public byte[] DataBuffer = new byte[1];
|
|
}
|
|
|
|
public delegate void OnReceiveLineCallback(string line);
|
|
public delegate void OnDisconnectedCallback(SocketException se);
|
|
|
|
public event OnReceiveLineCallback OnReceiveLine;
|
|
public event OnDisconnectedCallback OnDisconnected;
|
|
|
|
protected Socket _TCPSocket;
|
|
protected IAsyncResult _Result;
|
|
protected AsyncCallback _Callback;
|
|
protected string _Buffer = String.Empty;
|
|
|
|
public bool Connected
|
|
{
|
|
get
|
|
{
|
|
if (_TCPSocket != null && _TCPSocket.Connected)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public TCPPipe()
|
|
{
|
|
}
|
|
|
|
public SocketException Connect(string address, int port)
|
|
{
|
|
if (_TCPSocket != null && _TCPSocket.Connected)
|
|
Disconnect();
|
|
|
|
try
|
|
{
|
|
IPAddress ip;
|
|
if (!IPAddress.TryParse(address, out ip))
|
|
{
|
|
IPAddress[] ips = Dns.GetHostAddresses(address);
|
|
ip = ips[0];
|
|
}
|
|
_TCPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
|
IPEndPoint ipEndPoint = new IPEndPoint(ip, port);
|
|
_TCPSocket.Connect(ipEndPoint);
|
|
if (_TCPSocket.Connected)
|
|
{
|
|
WaitForData();
|
|
return null;
|
|
}
|
|
else
|
|
{
|
|
return new SocketException(10000);
|
|
}
|
|
}
|
|
catch (SocketException se)
|
|
{
|
|
return se;
|
|
}
|
|
}
|
|
|
|
public void Disconnect()
|
|
{
|
|
_TCPSocket.Disconnect(true);
|
|
}
|
|
|
|
public void SendData(byte[] data)
|
|
{
|
|
if (Connected)
|
|
_TCPSocket.Send(data);
|
|
else
|
|
throw new InvalidOperationException("socket is not connected");
|
|
}
|
|
|
|
public void SendLine(string message)
|
|
{
|
|
if (Connected)
|
|
{
|
|
byte[] byData = System.Text.Encoding.ASCII.GetBytes(message + "\n");
|
|
_TCPSocket.Send(byData);
|
|
}
|
|
else
|
|
{
|
|
throw new InvalidOperationException("socket is not connected");
|
|
}
|
|
}
|
|
|
|
void WaitForData()
|
|
{
|
|
try
|
|
{
|
|
if (_Callback == null) _Callback = new AsyncCallback(OnDataReceived);
|
|
SocketPacket packet = new SocketPacket();
|
|
packet.TCPSocket = _TCPSocket;
|
|
_Result = _TCPSocket.BeginReceive(packet.DataBuffer, 0, packet.DataBuffer.Length, SocketFlags.None, _Callback, packet);
|
|
}
|
|
catch (SocketException se)
|
|
{
|
|
Console.WriteLine(se.Message);
|
|
}
|
|
}
|
|
|
|
static char[] splitNull = { '\0' };
|
|
static string[] splitLines = { "\r", "\n", "\r\n" };
|
|
|
|
void ReceiveData(string data)
|
|
{
|
|
if (OnReceiveLine == null) return;
|
|
|
|
//string[] splitNull = { "\0" };
|
|
string[] line = data.Split(splitNull, StringSplitOptions.None);
|
|
_Buffer += line[0];
|
|
//string[] splitLines = { "\r\n", "\r", "\n" };
|
|
string[] lines = _Buffer.Split(splitLines, StringSplitOptions.None);
|
|
if (lines.Length > 1)
|
|
{
|
|
int i;
|
|
for (i = 0; i < lines.Length - 1; i++)
|
|
{
|
|
if (lines[i].Trim().Length > 0) OnReceiveLine(lines[i]);
|
|
}
|
|
_Buffer = lines[i];
|
|
}
|
|
}
|
|
|
|
void OnDataReceived(IAsyncResult asyn)
|
|
{
|
|
try
|
|
{
|
|
SocketPacket packet = (SocketPacket)asyn.AsyncState;
|
|
int end = packet.TCPSocket.EndReceive(asyn);
|
|
char[] chars = new char[end + 1];
|
|
System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
|
|
int charLen = d.GetChars(packet.DataBuffer, 0, end, chars, 0);
|
|
System.String data = new System.String(chars);
|
|
ReceiveData(data);
|
|
WaitForData();
|
|
}
|
|
catch (ObjectDisposedException)
|
|
{
|
|
Console.WriteLine("WARNING: Socket closed unexpectedly");
|
|
}
|
|
catch (SocketException se)
|
|
{
|
|
if (!_TCPSocket.Connected) OnDisconnected(se);
|
|
}
|
|
}
|
|
|
|
}
|