the program uses huge amount of memory after running several days

May 9 2005 11:50 AM
i have a program that receives TCP data and sends it to a message queue. it will run 24/7. it will eat up huge amount of memory after it runs for several days. The client side will send TCP data constantly and another program will pick up the message from the queue constantly too. Could somebody help me what the problem is in my code? The following is my source code of the program: using System; using System.Data; using System.Data.SqlClient; using System.Net; using System.Net.Sockets; using System.Text; using System.IO; using System.Threading; using System.Messaging; namespace TCP2MSG { /// /// Summary description for Class1. /// class Tcp2Msg { /// /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { int port = 0; string databaseName = String.Empty; string keyValue = String.Empty; string connectionString = String.Empty; string inputArgs = String.Empty; string queuePath = String.Empty; string sqlServer = "myserver"; byte[] data; SqlConnection myConnection; SqlCommand myCommand; if (args.Length == 0) { Console.WriteLine("Please enter the database name and key value"); inputArgs = Console.ReadLine(); } else { foreach (string inpt in args) { if (inpt.Substring(0,5) == "DBNM:") { databaseName = inpt.Substring(5,(inpt.Length-5)); } if (inpt.Substring(0,5) == "INFO:") { keyValue = inpt.Substring(5,(inpt.Length-5)); } if (inpt.Substring(0,5) == "DBAL:") { sqlServer = inpt.Substring(5,(inpt.Length-5)); } } } //Set up a connection to database and get the tcp port# and message queue path connectionString = "Data Source=" + sqlServer+";UID=xx;PWD=yyy;Initial Catalog=" + databaseName; myConnection = new SqlConnection(connectionString); myCommand = myConnection.CreateCommand(); myCommand.CommandType = CommandType.StoredProcedure; myCommand.CommandText = "pro_TCP2MSG_PORT"; myCommand.Parameters.Add("@Keyvalue",SqlDbType.VarChar,10); myCommand.Parameters.Add("@Port",SqlDbType.VarChar,10); myCommand.Parameters.Add("@QueuePath",SqlDbType.VarChar,40); myCommand.Parameters["@Keyvalue"].Value = keyValue; myCommand.Parameters["@Port"].Direction = ParameterDirection.Output; myCommand.Parameters["@QueuePath"].Direction = ParameterDirection.Output; try { myConnection.Open(); int rtn = myCommand.ExecuteNonQuery(); port = Convert.ToInt32(myCommand.Parameters["@Port"].Value.ToString()); queuePath = myCommand.Parameters["@QueuePath"].Value.ToString(); } catch (SqlException sexp) { Console.WriteLine("ERROR!! : " + sexp.Message.ToString()+ "Please check with your DBA regarding this error"); Console.WriteLine("The program will terminate in 10 seconds"); Thread.Sleep(10000); return; } catch { Console.WriteLine("ERROR!! : No data was found for the input value " + keyValue.ToUpper() + " Please check with your DBA regarding this error"); Console.WriteLine("The program will terminate in 10 seconds"); Thread.Sleep(10000); return; } finally { if (myConnection.State == ConnectionState.Open) myConnection.Close(); myCommand.Dispose(); myConnection.Dispose(); //GC.Collent() doesn't help to clean up the memory :( GC.Collect(); } Socket server = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); IPEndPoint myself = new IPEndPoint(IPAddress.Any,port); server.Bind(myself); server.Listen(5); Socket client = server.Accept(); IPEndPoint newClient = (IPEndPoint)client.RemoteEndPoint; string conTime = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(); Console.WriteLine("Connected with {0} at port# {1} on {2}",newClient.Address,newClient.Port,conTime); while (true) { try { data = ReceiveVarData(client); if (data.Length == 0) { string disTime = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(); Console.WriteLine("Disconnected with {0} on {1}", newClient.Address,disTime.ToString()); client.Close(); client = server.Accept(); newClient = (IPEndPoint)client.RemoteEndPoint; conTime = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(); Console.WriteLine("Connected with {0} at port# {1} on {2}",newClient.Address,newClient.Port,conTime); } else { SendToQueue(data,queuePath); } } catch(SocketException sexp) { Console.WriteLine("ERROR! Cannot receive data from the client..."); Console.WriteLine("DETAIL ERROR: " + sexp.Message.ToString()); Console.WriteLine("Disconnecting from client and waiting for a new client..."); client.Close(); client = server.Accept(); newClient = (IPEndPoint)client.RemoteEndPoint; conTime = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToLongTimeString(); Console.WriteLine("Connected with {0} at port# {1} on {2}",newClient.Address,newClient.Port,conTime); } finally { data = null; } } } private static void SendToQueue(byte[] data, string queuePath) { string tcpMsg = Encoding.ASCII.GetString(data); Message queMsg = new Message(tcpMsg,new XmlMessageFormatter()); Console.WriteLine("Sending message length " + tcpMsg.Length.ToString() + " to the queue " + queuePath); if (!MessageQueue.Exists(@".\Private$\" + queuePath)) { MessageQueue newQueue = MessageQueue.Create(@".\Private$\"+queuePath); newQueue.SetPermissions("Everyone",MessageQueueAccessRights.FullControl); newQueue.Label = queuePath; newQueue.Send(queMsg); // new vern code newQueue.Close(); newQueue.Dispose(); queMsg.Dispose(); } else { MessageQueue existingQueue = new MessageQueue(@".\Private$\" + queuePath); existingQueue.Send(queMsg); // new vern code existingQueue.Close(); existingQueue.Dispose(); queMsg.Dispose(); } //GC.Collect() doesn't help to clean up the memory, but slows down the performance probably GC.Collect(); } private static byte[] ReceiveVarData(Socket s) { int total = 0; int recv = 0; //The first 4 byte will contain the total length of the message in ASCII format byte[] datasize = new byte[4]; int size = 0; byte[] data ; try { recv = s.Receive(datasize,0,4,SocketFlags.None); size = Convert.ToInt32(Encoding.ASCII.GetString(datasize)); int dataleft = (int)size; data = new byte[size]; while (total < (int)size) { recv = s.Receive(data,total,dataleft,SocketFlags.None); if (recv == 0) break; total += recv; dataleft -= recv; } } catch { data = new byte[0]; } finally { GC.Collect(); } return data; } } }

Answers (2)