I am trying to integrate Thrift with ActiveMQ in c#.My publisher and subscriber messages are getting serialized and de-serialized right way. But at the very last step that I am getting the exception like "Remote side has closed" under TJSONProtocol. This is the following line which revels the error.
///<summary>
/// Return and consume the next byte to be Read, either taking it from the
/// data buffer if present or getting it from the transport otherwise.
///</summary>
public byte Read()
{
if (hasData)
{
hasData = false;
}
else
{
proto.trans.ReadAll(data, 0, 1);
}
return data[0];
}
This is the exact error I am getting
This is my custom transports for server side
class ThriftJMSServerTransport : TServerTransport
{
Listener listener = new Listener();
protected override TTransport AcceptImpl()
{
try
{
return new ActiveMQTransport().Accept();
// return listener.Accept(); ;
}
catch (Exception ex)
{
return null;
}
}
public override void Close()
{
throw new NotImplementedException();
}
public override void Listen()
{
// listener.Initialize();
listener.Intitializelistner();
// throw new NotImplementedException();
}
}
ActiveMQTransport Class
public delegate void MessageReceivedEventHandler(string message, string correlationId);
public class ActiveMQTransport : TTransport
{
private MemoryStream _inputStream;
private MemoryStream _outputStream;
private ActiveMQServerUtil _activeMq;
private string _corelationId;
/// <summary>
/// constructor
/// </summary>
/// <param name="activeMq"></param>
public ActiveMQTransport()
: this(new MemoryStream(), new MemoryStream())
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="inputStream"></param>
/// <param name="outputstream"></param>
/// <param name="activeMq"></param>
public ActiveMQTransport(MemoryStream inputStream, MemoryStream outputstream)
{
_inputStream = inputStream;
_outputStream = outputstream;
_activeMq = ActiveMQServerUtil.GetActiveMQServerUtil();
_activeMq.MessageReceived += new MessageReceivedEventHandler(_activeMq_MessageReceived);
}
public ActiveMQTransport Accept()
{
IMessage message = _activeMq.Receive();
ITextMessage textMessage = message as ITextMessage;
_activeMq_MessageReceived(textMessage.Text, textMessage.NMSCorrelationID);
return this;
}
/// <summary>
/// Read Message and write onto transport input stream
/// </summary>
/// <param name="message"></param>
/// <param name="correlationId"></param>
private void _activeMq_MessageReceived(string message, string correlationId)
{
byte[] opMessage = Encoding.UTF8.GetBytes(message);
_corelationId = correlationId;
//_inputStream = new MemoryStream();
_inputStream.Write(opMessage, 0, message.Length);
_inputStream.Position = 0;
Console.WriteLine("CorelationId: {0}, Listner Message: {1}"
, correlationId, message);
}
public override bool IsOpen
{
get { return true; }
}
public override void Open()
{
}
public override void Close()
{
}
public override int Read(byte[] buf, int off, int len)
{
try
{
int i= _inputStream.Read(buf, off, len);
return i;
}
catch(Exception ex)
{
return 0;
}
}
public override void Write(byte[] buf, int off, int len)
{
_outputStream.Write(buf, off, len);
}
/// <summary>
/// Flush result to ActiveMQ
/// </summary>
public override void Flush()
{
_activeMq.Send(Encoding.UTF8.GetString(_outputStream.ToArray()), this._corelationId);
_outputStream = new MemoryStream();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
}
}
Listner class
public class Listener
{
public const string DESTINATION = "Topic1to2";
ActiveMQTransport activeMq = new ActiveMQTransport();
public static Queue<IMessage> Processqueue = new Queue<IMessage>();
public Listener()
{
}
private void PutMessageinQueue(ITextMessage message)
{
if (!string.IsNullOrEmpty(message.Text))
{
Processqueue.Enqueue(message);
}
}
private void consumer_Listener(IMessage message)
{
ITextMessage textMessage = message as ITextMessage;
Console.WriteLine(textMessage.Text);
if (!string.IsNullOrEmpty(textMessage.Text))
{
Processqueue.Enqueue(textMessage);
}
}
public void Intitializelistner()
{
IConnectionFactory factory = new
ConnectionFactory("activemq:tcp://localhost:61616/");
//Create the connection
using (IConnection connection =
factory.CreateConnection())
{
// connection.ClientId = "testing listener";
connection.Start();
//Create the Session
using (ISession session = connection.CreateSession())
{
//Create the Consumer
IMessageConsumer consumer = session.CreateConsumer(
new Apache.NMS.ActiveMQ.Commands.ActiveMQTopic(
DESTINATION));
consumer.Listener += new MessageListener(
consumer_Listener);
Console.ReadLine();
}
}
}
//static void consumer_Listener1(IMessage message)
//{
// Console.WriteLine("Receive: " +
// ((ITextMessage)message).Text);
//}
}
publisher class
public class Publisher : BaseClass
{
public const string DESTINATION = "Topic2to1";
public Publisher()
{
}
public void SendMessage(string message)
{
IConnectionFactory factory = new ConnectionFactory("activemq:tcp://localhost:61616/");
using (IConnection connection = factory.CreateConnection())
{
//Create the Session
using (ISession session = connection.CreateSession())
{
//Create the Producer for the topic/queue
IMessageProducer prod = session.CreateProducer(new ActiveMQTopic(DESTINATION));
//Send Messages
// int i = 0;
// while (!Console.KeyAvailable)
{
ITextMessage msg = prod.CreateTextMessage();
msg.Text = message;
Console.WriteLine("Sending: " + msg.Text);
prod.Send(msg);
System.Threading.Thread.Sleep(250);
// i++;
}
}
}
Console.ReadLine();
}
}
Following is the client side custom transport
public class ThriftJmsTransport : TTransport
{
public delegate void MessageReceivedEventHandler(string message);
protected MemoryStream inputStream=new MemoryStream();
protected MemoryStream outputStream=new MemoryStream();
Listener listener = new Listener();
public ThriftJmsTransport()
{
}
public ThriftJmsTransport(MemoryStream inputStream, MemoryStream outputStream)
{
this.inputStream = inputStream;
this.outputStream = outputStream;
}
public Stream OutputStream
{
get { return outputStream; }
}
public Stream InputStream
{
get { return inputStream; }
}
public override void Close()
{
if (inputStream != null)
{
inputStream.Close();
inputStream = null;
}
if (outputStream != null)
{
outputStream.Close();
outputStream = null;
}
}
public override bool IsOpen
{
get { return true; }
}
public override void Open()
{
// listener.Initialize();
listener.Intitializelistner();
// Listener.MessageReceived += new MessageReceivedEventHandler(_activeMq_MessageReceived);
}
void _activeMq_MessageReceived(string message)
{
inputStream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(message));
Console.WriteLine(message);
inputStream.Position = 0;
// _signal.Set();
}
public override int Read(byte[] buf, int off, int len)
{
if (inputStream == null)
{
throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot read from null inputstream");
}
return inputStream.Read(buf, off, len);
}
public override void Write(byte[] buf, int off, int len)
{
if (!outputStream.CanWrite)
outputStream = new MemoryStream();
outputStream.Write(buf, off, len);
}
public override void Flush()
{
//if (outputStream == null)
//{
// throw new TTransportException(TTransportException.ExceptionType.NotOpen, "Cannot flush null outputstream");
//}
if (outputStream != null)
{
// StreamReader reader = new StreamReader(outputStream);
string text = System.Text.Encoding.Default.GetString(outputStream.ToArray());
Send(text);
}
}
public void Send(string message)
{
var publisher=new Publisher();
publisher.SendMessage(message);
}
#region " IDisposable Support "
private bool _IsDisposed;
// IDisposable
protected override void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (InputStream != null)
InputStream.Dispose();
if (OutputStream != null)
OutputStream.Dispose();
}
}
_IsDisposed = true;
}
#endregion
}
Related
I'm trying to create a TCP Client-Server connection, the client can connect to the server successfully, but I can't receive the data I'm sending from the server and I get this Error:
NullReferenceException: Object reference not set to an instance of an object ClientHandlePackets.HandleDataPackets (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:89) ClientHandlePackets.HandleData (System.Byte[] data) (at Assets/Client/Scripts/ClientHanlePackets.cs:61) ClientTCP.Update () (at Assets/Client/Scripts/ClientTCP.cs:31)
How can I Solve this?
c#
using System.Collections.Generic;
using UnityEngine;
public enum ServerPackets
{
S_INFORMATION = 1,
S_EXECUTEMETHODONCLIENT,
}
public class ClientHandlePackets : MonoBehaviour
{
public static Bytebuffer playerbuffer;
public delegate void Packet_(byte[] data);
private static Dictionary<long, Packet_> packets;
private static long pLength;
private void Awake()
{
initalizePackets();
}
private static void initalizePackets()
{
packets = new Dictionary<long, Packet_>();
packets.Add((long)ServerPackets.S_INFORMATION, PacketInformation);
}
public static void HandleData(byte[] data)
{
byte[] Buffer;
Buffer = (byte[])data.Clone();
if (playerbuffer == null) { playerbuffer = new Bytebuffer(); };
playerbuffer.WriteBytes(Buffer);
if (playerbuffer.Count() == 0)
{
playerbuffer.Clear();
return;
}
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength <= 0)
{
playerbuffer.Clear();
return;
}
}
while (pLength > 0 & pLength <= playerbuffer.Length() - 8)
{
if (pLength <= playerbuffer.Length() - 8)
{
playerbuffer.ReadLong(); //REads out the packet identifier
data = playerbuffer.Readbytes((int)pLength); // Gets the full package length
HandleDataPackets(data);
}
pLength = 0;
if (playerbuffer.Length() >= 8)
{
pLength = playerbuffer.ReadLong(false);
if (pLength < 0)
{
playerbuffer.Clear();
return;
}
}
}
}
private static void HandleDataPackets(byte[] data)
{
long packetIdentifier;
Bytebuffer Buffer;
Packet_ packet;
Buffer = new Bytebuffer();
Buffer.WriteBytes(data);
packetIdentifier = Buffer.ReadLong();
Buffer.Dispose();
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
}
private static void PacketInformation(byte[] data)
{
Bytebuffer buffer = new Bytebuffer();
buffer.WriteBytes(data);
long packetIdentifier = buffer.ReadLong();
string msg1 = buffer.Readstring();
string msg2 = buffer.Readstring();
int Level = buffer.ReadInteger();
Debug.Log(msg1);
Debug.Log(msg2);
Debug.Log(Level);
}
}
using System;
using System.Net.Sockets;
using UnityEngine;
using UnityEngine.UI;
public class ClientTCP: MonoBehaviour
{
public Text info;
public static ClientTCP instance;
public TcpClient client;
public NetworkStream mystream;
private byte[] AsynchBuffer;
public bool IsConnected;
public byte[] Receivebyte;
public bool handleData = false;
private string IP_Adress= "127.0.0.1";
private int port=5555;
private void Awake()
{
instance = this;
}
private void Update()
{
if (handleData == true)
{
ClientHandlePackets.HandleData(Receivebyte);
handleData = false;
}
}
public void Connect()
{
Debug.Log("Trying to connect to the sever...");
client = new TcpClient();
client.ReceiveBufferSize = 4096;
client.SendBufferSize = 4096;
AsynchBuffer = new byte[8192];
try
{
client.BeginConnect(IP_Adress, port, new AsyncCallback(ConnectCallback), client);
}
catch
{
Debug.Log("unable to connect to the server");
}
}
private void ConnectCallback(IAsyncResult result)
{
try
{
client.EndConnect(result);
if (client.Connected == false)
{
return;
}
else
{
mystream = client.GetStream();
mystream.BeginRead(AsynchBuffer,0,8192,OnRecieveData,null);
IsConnected = true;
Debug.Log("You are connected to the server successfully!");
}
}
catch (Exception)
{
IsConnected = false;
return;
}
}
private void OnRecieveData(IAsyncResult result)
{
try
{
int packetlength = mystream.EndRead(result);
Receivebyte = new byte[packetlength];
Buffer.BlockCopy(AsynchBuffer, 0, Receivebyte, 0, packetlength);
if (packetlength == 0)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
handleData = true;
mystream.BeginRead(AsynchBuffer, 0, 8192, OnRecieveData, null);
}
catch (Exception)
{
Debug.Log("disconnected");
Application.Quit();
return;
}
}
}
the problem is here:
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet.Invoke(data);
}
to avoid this error you can use
if (packets.TryGetValue(packetIdentifier, out packet))
{
packet?.Invoke(data);
}
But the problem is that i don't see where you fill your packets' dictionary with data in your code.
Can you show your ByteBuffer class?
I build a middle ware server.
I have 5(or 6) clients(different computer/IP address), and every client can have up to 6 connection -> max 36 connection to the server.
It is better to use only 1 port for all (e.g. 9000) or one different port for every client(e.g. 9000-9005) ?
I write me a simple test server(see code).
It worked like expected but maybe there is some room for optimization.
Thanks
My TCP server
public class TCPServerMulti : IDisposable
{
private static TcpListener _tcpListener;
private string _ipAdress = "";
private int _port = 9050;
private readonly Thread _listener;
private readonly bool _running;
private int cc = 0; //Test Counter
public string IPAdress
{
get { return _ipAdress; }
set { _ipAdress = value; }
}
public TCPServerMulti(int port)
{
if(port>0)
_port = port;
_running = true;
string sHostName = Dns.GetHostName();
IPAdress = "";
//Only use the first address -> need to change
IPAddress[] localAddress = Dns.GetHostAddresses(sHostName);
foreach (IPAddress ipAddress in localAddress)
{
if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
{
_tcpListener = new TcpListener(ipAddress, _port);
IPAdress = ipAddress.ToString();
break;
}
}
if (IPAdress == "")
{
Console.Writeline("TCP Error");
return;
}
_tcpListener.Start();
_listener = new Thread(Listen) { IsBackground = true };
_listener.Start();
}
public TCPServerMulti():this(-1)
{}
//listening for clients
public void Listen()
{
try
{
while(_running)
{
cc++;
//create a own client object for every connection
TCPClientData cd = new TCPClientData(this, ""+cc, _tcpListener.AcceptTcpClient());
cd.StartClient();
if (ClientConnected != null) ClientConnected("Connected: " + cc);
}
_tcpListener.Stop();
}
catch (Exception)
{
}
}
public void Dispose()
{
_listener.Abort();
_tcpListener.Stop();
}
//Handle for Mainthread
internal void ReceiveClient(TCPClientData sender, string msg)
{
if (ReceiveMsg != null)
ReceiveMsg(sender, msg);
}
public delegate void ReceiveEventHandler(TCPClientData sender, string msg);
public event ReceiveEventHandler ReceiveMsg;
public delegate void ConnectedEventHandler(string msg);
public event ConnectedEventHandler ClientConnected;
}
Clientdata object
public class TCPClientData : IDisposable
{
private TCPServerMulti _master;
private byte[] _data;
private NetworkStream _networkStream;
private int _received;
private TcpClient _tcpClient;
private Thread _worker;
private bool _wrunning;
private string _id;
public TCPClientData(TCPServerMulti master,string id,TcpClient client)
{
_data = new byte[1024];
_master = master;
_id = id;
_tcpClient = client;
}
public string ID
{
get { return _id; }
}
private string ByteArrayToString(byte[] arr)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetString(arr);
}
private byte[] StringToByteArray(string data)
{
UTF8Encoding enc = new UTF8Encoding();
return enc.GetBytes(data);
}
// Reading Data
private void Worker()
{
try
{
while (_wrunning)
{
if (_networkStream.DataAvailable)
{
_received = _networkStream.Read(_data, 0, _data.Length);
string s = ByteArrayToString(_data);
_master.ReceiveClient(this, s.Substring(0, _received));
}
else
{
Thread.Sleep(20);
}
}
_networkStream.Close();
_tcpClient.Close();
}
catch (Exception)
{ }
}
public void Dispose()
{
_worker.Abort();
_networkStream.Close();
_tcpClient.Close();
}
public void StartClient()
{
_networkStream = _tcpClient.GetStream();
_networkStream.ReadTimeout = 200;
_wrunning = true;
_worker = new Thread(Worker) { IsBackground = true };
_worker.Start();
}
public void StopClient()
{
_wrunning = false;
Thread.Sleep(700);
}
//Sending Data
public void WriteData(string msg)
{
byte[] b = StringToByteArray(msg);
_networkStream.Write(b,0,b.Length);
_networkStream.Flush();
}
}
Main Thread
static void Main(string[] args)
{
//Create Server
TCPServerPlugin.TCPServerMulti server=new TCPServerMulti(12345);
server.ClientConnected += Server_ClientConnected;
server.ReceiveMsg += Server_ReceiveMsg;
while (true)
{
}
}
//Callbacks
private static void Server_ClientConnected(string msg)
{
Console.WriteLine(msg);
}
private static void Server_ReceiveMsg(TCPClientData sender, string msg)
{
Console.WriteLine(string.Format("Sender: {0} -> MSG:{1}",sender.ID,msg));
if (msg == "!!X")
{
sender.Dispose();
sender = null;
}
else if(msg=="DATE")
sender.WriteData(DateTime.Now.ToLongDateString());
else if(msg=="TIME")
sender.WriteData(DateTime.Now.ToShortTimeString());
}
I've been trying for several days to make the client detect it when the server connection is closed and make a loop of connection attempts until it detects the available connection (open the server) and when I try closing the connection with Client.Close and shutdown (shutdown.both) stops the application
thank you if you could help me that I'm not correcting mistakes or solving the code
[DllImport("winmm.dll", EntryPoint = "mciSendStringA")]
public static extern void mciSendStringA(string comandonow, string retornonow, long longitudnow, long callbacknow);
public static TcpClient QKICDdjIKo = new TcpClient();
static IPEndPoint MjDHEHn = null;
static IPHostEntry hostEntry;
static List<TcpClient> countConnections = new List<TcpClient>();
static StreamReader reader;
private static byte[] _readBuffer;
private static byte[] _tempHeader;
public static bool Connected { get; private set; }
public static bool Exiting { get; private set; }
//
public static int BUFFER_SIZE { get { return 1024 * 16; } } // 16KB
public static int HEADER_SIZE { get { return 4; } } // 4B
private static bool IsConnectionSuccessful = false;
private static ManualResetEvent TimeoutObject = new ManualResetEvent(false);
private static Exception socketexception;
public static bool isconnected;
public static void Connection()
{
TimeoutObject.Reset();
socketexception = null;
try
{
if (!QKICDdjIKo.Connected)
{
_readBuffer = new byte[BUFFER_SIZE];
_tempHeader = new byte[HEADER_SIZE];
hostEntry = Dns.GetHostEntry("noip host");
var ip = hostEntry.AddressList[0];
MjDHEHn = new IPEndPoint(IPAddress.Parse(ip.ToString()), 4004);
QKICDdjIKo.Connect(MjDHEHn); // Option 1
// QKICDdjIKo.BeginConnect("127.0.0.1", 4004, new AsyncCallback(khmcbmPmGPCfIOcPKOBONAbnGnfFIJnpREd), QKICDdjIKo); //Option 2
OperatingSystem os_info = Environment.OSVersion;
ConnectedVerify(Environment.UserName.ToString());
QKICDdjIKo.GetStream().BeginRead(_readBuffer, 0, _readBuffer.Length, ReadMSG, 0);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private static void CallBackMethod(IAsyncResult asyncresult)
{
try
{
IsConnectionSuccessful = false;
TcpClient tcpclient = asyncresult.AsyncState as TcpClient;
if (tcpclient.Client != null)
{
tcpclient.EndConnect(asyncresult);
IsConnectionSuccessful = true;
}
}
catch (Exception ex)
{
IsConnectionSuccessful = false;
socketexception = ex;
}
finally
{
TimeoutObject.Set();
}
}
public Form1()
{
InitializeComponent();
Connect();
}
public static void Connect()
{
while (!Exiting) // Main Connect Loop
{
if (!Connected)
{
Thread.Sleep(100 + new Random().Next(0, 250));
Connection();
Thread.Sleep(200);
Application.DoEvents();
}
while (Connected) // hold client open
{
Application.DoEvents();
Thread.Sleep(2500);
}
if (Exiting)
{
//QKICDdjIKo.Close();
return;
}
Thread.Sleep(3000 + new Random().Next(250, 750));
}
}
public static void ReadMSG(IAsyncResult now)
{
try
{
while (true)
{
reader = new StreamReader(QKICDdjIKo.GetStream());
Rd(reader.ReadLine());
QKICDdjIKo.GetStream().BeginRead(_readBuffer, 0, _readBuffer.Length, ReadMSG, 0);
}
}
catch
{
}
}
public static void HjoLNkEHFaqQCp(string texto)
{
try
{
StreamWriter DpBoDcECG = new StreamWriter(QKICDdjIKo.GetStream());
DpBoDcECG.WriteLine(texto);
DpBoDcECG.Flush();
}
catch
{
//
}
}
public static void Rd(string msg)
{
}
static void Status(string msg)
{
try
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("STATUS|" + msg);
writer.Flush();
}
catch
{
}
}
static void ConnectedVerify(string msg)
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("CONNECTED|" + msg);
writer.Flush();
}
static void usr(string msg)
{
StreamWriter writer = new StreamWriter(QKICDdjIKo.GetStream());
writer.WriteLine("USER|" + msg);
writer.Flush();
}
In Unity3d Webgl I download and write big file (about 100 mb and more) to cache (indexeddb).
I downloaded file with UnityWebRequest and write file in downloadHandler.
Sometimes after call filestream.Write() or filestream.Flush() Chrome will crash.
Exception not available, only crash tab of chrome.
Crash happens abount in 50 percent of dowloads.
public class Downloader : MonoBehaviour
{
public IEnumerator DownloadFileCoroutine(string url, string filePath, string clientName, int fileId, Action<int> downloadedCallback)
{
var currentWebRequest = UnityWebRequest.Get(url);
currentWebRequest.downloadHandler = new ToFileDownloadHandler(new byte[64 * 1024], filePath);
var downloadHendler = (currentWebRequest.downloadHandler as ToFileDownloadHandler);
currentWebRequest.Send();
while (!currentWebRequest.isDone && !currentWebRequest.isNetworkError && !currentWebRequest.isHttpError)
{
if (currentWebRequest.isNetworkError)
{
yield break;
}
}
if (currentWebRequest.isNetworkError)
{
downloadHendler.Cancel();
}
else
{
/// suceess
}
}
public class ToFileDownloadHandler : DownloadHandlerScript
{
private int _expected = -1;
private long _received = 0;
private readonly string _filepath;
private readonly FileStream _fileStream = null;
private bool _canceled = false;
public ToFileDownloadHandler(byte[] buffer, string filepath) : base(buffer)
{
CreateDir();
_filepath = filepath;
_fileStream = new FileStream(filepath, FileMode.Create, FileAccess.Write);
}
protected override byte[] GetData() { return null; }
protected override bool ReceiveData(byte[] data, int dataLength)
{
if (data == null || data.Length < 1)
{
return false;
}
_received += dataLength;
if (!_canceled)
{
_fileStream.Write(data, 0, dataLength);
_fileStream.Flush();
}
return true;
}
protected override float GetProgress()
{
if (_expected < 0) return 0;
return (float)_received / _expected;
}
protected override void CompleteContent()
{
_fileStream.Close();
_isComplete = true;
}
protected override void ReceiveContentLength(int contentLength)
{
_expected = contentLength;
}
public void Cancel()
{
if (_canceled) return;
_canceled = true;
if (_fileStream != null)
{
_fileStream.Close();
}
File.Delete(_filepath);
}
private void CreateDir()
{
cachePath = Application.persistentDataPath;
if (!Directory.Exists(cachePath))
{
Directory.CreateDirectory(cachePath);
}
}
}
}
I am working on a very simply server/client program. I am wanting to send a costume class from the server to the client and vice versa. After some research, I figured out how to send an object and receive it. Although after I send an object, I can't seem to send any more. The send message doesn't throw any exceptions but the receiver never gets the message. Any help would be appreciated.
public abstract class baseClient
{
private Player player;
private Thread chat;
private NetworkStream messageStream;
private BinaryFormatter formatter;
private List<MSG> MSGM;
private List<String> MSGS;
private BinaryReader reader;
private BinaryWriter writer;
private String ExceptionMessage;
public baseClient()
{
formatter = new BinaryFormatter();
MSGM = new List<MSG>();
MSGS = new List<String>();
chat = new Thread(new ThreadStart(doChat));
chat.Start();
}
public abstract void doChat();
public void setMessageStream(NetworkStream stream) { messageStream = stream; }
public void setReader(BinaryReader reader) { this.reader = reader; }
public void setFormatter(BinaryFormatter formatter) { this.formatter = formatter; }
public void setPlayer(Player player) { this.player = player; }
public void setExceptionMessage(String message) { ExceptionMessage = message; }
public void clearMessageMSG() { MSGM.Clear(); }
public void clearStringMSG() { MSGS.Clear(); }
public void setWriter(BinaryWriter writer) { this.writer = writer; }
public NetworkStream getMessageStream() { return messageStream; }
public void addMSGM(MSG obj) { MSGM.Add(obj); }
public void addMSGS(String obj) { MSGS.Add(obj); }
public BinaryReader getReader() { return reader; }
public BinaryFormatter getFormatter() { return formatter; }
public List<MSG> getMessageMSG() { return MSGM; }
public List<String> getStringMSG() { return MSGS; }
public BinaryWriter getWriter() { return this.writer; }
public Player getPlayer() { return player; }
public void handleInput()
{
try
{
Object obj = getObject();
if (obj != null)
{
if (obj is Player)
setPlayer((Player)obj);
if (obj is MSG)
addMSGM((MSG)obj);
else if (obj is String)
addMSGS((String)obj);
}
}
catch (Exception e)
{
setExceptionMessage(e.ToString());
}
}
public Object getObject()
{
try
{
Stream stream = getReader().BaseStream;
object obj = formatter.Deserialize(stream);
stream.Flush();
// stream.Close();
return obj;
}
catch (Exception e)
{
ExceptionMessage= e.ToString();
return e;
}
}
public String getString()
{
try
{
string reply = reader.ReadString();
return reply;
}
catch (Exception e)
{
ExceptionMessage = e.ToString();
return null;
}
}
public bool sendMessage(Object msg)
{
try
{
Byte[] buffer = SerializeMultipleObjects(msg).GetBuffer();
getMessageStream().Write(buffer, 0, buffer.Length);
getMessageStream().Flush();
return true;
}
catch (Exception e)
{
setExceptionMessage(e.ToString());
return false;
}
}
public bool sendString(String msg)
{
try
{
writer.Write(msg);
writer.Flush();
return true;
}
catch (Exception e)
{
setExceptionMessage(e.ToString());
return false;
}
}
private MemoryStream SerializeMultipleObjects(Object obj)
{
MemoryStream stream = new MemoryStream();
getFormatter().Serialize(stream, obj);
stream.Flush();
return stream;
}
}
I recommend you use an established messaging framework such as WCF. It you insist on writing your own TCP/IP protocol, you will need message framing.