/*
* description: "Provides methods to connect to a xebra server, to send and receive string messages."
* date: "$Date: 2009-05-01 11:33:29 -0700 (Fri, 01 May 2009) $"
* revision: "$Revision: 78473 $"
* copyright: "Copyright (c) 1985-2007, Eiffel Software."
* license: "GPL version 2 see http://www.eiffel.com/licensing/gpl.txt)"
* licensing_options: "Commercial license is available at http://www.eiffel.com/licensing"
* copying: ""
* source: "[
* Eiffel Software
* 5949 Hollister Ave #B, Goleta, CA 93117
* Telephone 805-685-1006, Fax 805-685-6869
* Website http://www.eiffel.com
* Customer support http://support.eiffel.com
* ]"
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Net.Sockets;
namespace Xebra
{
///
/// Provides methods to connect to a xebra server, to send and receive string messages.
///
class XServerConnection
{
#region Fields
///
/// The Socket
///
TcpClient socket;
///
/// The logger to store debug and error messages
///
XLogger log;
///
/// The config info read from the web.config file
///
XConfig config;
#endregion
#region Constants
///
/// The maximal size of a message fragment
///
private static int FRAG_SIZE = 65536;
///
/// The maximal number of fragments of a message
///
private static int MAX_FRAGS = 1000;
#endregion
///
/// Constructor
///
/// A logger to write debug and error messages
/// A configuration
public XServerConnection(XLogger log, XConfig config)
{
this.config = config;
this.log = log;
}
///
/// Connects to the server
///
/// Returns true if a connection could be established
public bool connect()
{
try
{
socket = new TcpClient(config.Host, config.Port);
return true;
}
catch
{
log.Error("Cannot connect the Xebra Server.");
return false;
}
}
///
/// Sends a string to the server
///
/// The message
/// Returns true if there was no error
public bool sendMessage(String message)
{
if (socket == null)
{
log.Error("Not connected!");
return false;
}
byte[] msgFragAndLength = new byte[FRAG_SIZE + 4];
byte[] encodedMsgLengthByte = new byte[4];
int bytesSent = 0;
int numBytes = 0;
byte[] messageByte = Encoding.UTF8.GetBytes(message);
uint totalMessageLength = (uint)messageByte.Length;
string oute;
while (bytesSent < totalMessageLength)
{
if ((totalMessageLength - bytesSent) > FRAG_SIZE)
{
encodedMsgLengthByte = System.BitConverter.GetBytes((int)XEncoder.encodeNatural((uint)FRAG_SIZE, 1));
//Convert to bigendian
Array.Reverse(encodedMsgLengthByte);
System.Buffer.BlockCopy(encodedMsgLengthByte, 0, msgFragAndLength, 0, encodedMsgLengthByte.Length);
System.Buffer.BlockCopy(messageByte, bytesSent, msgFragAndLength, encodedMsgLengthByte.Length, FRAG_SIZE);
oute = System.Text.ASCIIEncoding.ASCII.GetString(msgFragAndLength);
numBytes = socket.Client.Send(msgFragAndLength, msgFragAndLength.Length, SocketFlags.None);
}
else
{
encodedMsgLengthByte = System.BitConverter.GetBytes((int)XEncoder.encodeNatural(totalMessageLength - (uint)bytesSent, 0));
//Convert to bigendian
Array.Reverse(encodedMsgLengthByte);
System.Buffer.BlockCopy(encodedMsgLengthByte, 0, msgFragAndLength, 0, encodedMsgLengthByte.Length);
System.Buffer.BlockCopy(messageByte, bytesSent, msgFragAndLength, encodedMsgLengthByte.Length, (int)totalMessageLength - (int)bytesSent);
oute = System.Text.ASCIIEncoding.ASCII.GetString(msgFragAndLength);
numBytes = socket.Client.Send(msgFragAndLength, (int)totalMessageLength - (int)bytesSent + 4, SocketFlags.None);
}
if (numBytes < 5)
{
log.Error("Failed to send!");
return false;
}
else
{
bytesSent += numBytes - 4;
}
}
return true;
}
///
/// Waits to receive a string from the server
///
/// Used to store the received message
/// Returns true if no error occurred during receiving
public bool receiveMessage(out string responseMessage)
{
bool flag = false;
byte[] encodedLengthByte = new byte[4];
uint encodedLength;
uint length;
int fragCounter = 0;
int numBytes;
string message = "";
byte[] msgBuf = new byte[FRAG_SIZE + 4];
responseMessage = "";
do
{
//Read Length
numBytes = socket.Client.Receive(encodedLengthByte, 4, SocketFlags.None);
if (numBytes != 4)
{
log.Error("Could not receive 4 bytes for length.");
return false;
}
//Convert to littleEndian
Array.Reverse(encodedLengthByte);
encodedLength = System.BitConverter.ToUInt32(encodedLengthByte, 0);
length = XEncoder.decodeNatural(encodedLength);
flag = XEncoder.decodeFlag(encodedLength);
if (length < 1 || length > FRAG_SIZE)
{
log.Error("Illegal msg length " + length);
return false;
}
//Read Msg
numBytes = socket.Client.Receive(msgBuf, (int)length, SocketFlags.None);
message += System.Text.ASCIIEncoding.ASCII.GetString(msgBuf).Substring(0,numBytes);
if (fragCounter > MAX_FRAGS)
{
log.Error ("Maximum fragments reached, aborting.");
return false;
}
fragCounter++;
} while (flag);
responseMessage = message;
return true;
}
}
}