1

I wanna send data from client to server. There are two queues. in client side and in server side. I want to my client to be connected to the server and send all the data in client queue to the server. In server side I wanna accept all the clients and get all objects and add to the server side queue

Client code :

Queue<Person> clientQueue;   // This is the client side queue

IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 15884);
var client = new TcpClient();

while(!clientQueue.IsEmpty)
{
    Person personObj = clientQueue.Dequeue();

    client.Connect(serverEndPoint);
    NetworkStream clientStream = client.GetStream();
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(clientStream, personObj);
    clientStream.Flush();
}

Server Side :

Queue<Person> serverQueue;   // This is the server side queue

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 15884);
TcpListener tcpListener = new TcpListener(ipEndPoint);


while(true)
{
    TcpClient client = tcpListener.AcceptTcpClient();
    NetworkStream clientStream = tcpClient.GetStream();
    BinaryFormatter bf = new BinaryFormatter();
    Person person = (Person)bf.Deserialize(clientStream);
    tcpClient.Close();

    serverQueue.Enqueue(person);
}

I know above code is not working. I just wanna sketch my design. Can someone please send me the code example. How to send client queue to server queue..

Thanks..

Michael Petrotta
  • 59,888
  • 27
  • 145
  • 179
Sency
  • 2,818
  • 8
  • 42
  • 59
  • "above code is not working" isn't very descriptive. What happens when you try it? – Jon Skeet Jul 23 '11 at 07:35
  • what is the .net framework you are using? – Jalal Said Jul 23 '11 at 07:36
  • @Jon : already I have developed this to, Connect to Server -> send only one object -> dispose the client. Now I need to change my program to send a data queue to server side. I don't have an idea about how to change my program to send an entire queue to server side. That why I put just a sketchy code here. :) – Sency Jul 23 '11 at 07:54
  • @Kushan: Aside from the fact that your server is assuming a single Person per connection, but you're trying to push multiple objects down from the client, it should work how you've got it. It won't be very efficient, but it would be a starting point. Get something simple working first, and then move on from there. – Jon Skeet Jul 23 '11 at 08:12
  • @Jon. Yes jon. already server is assuming one Person per connection. But now I need to change my program to get multiple Persons( Queue of persons) from each clients. Here I dont have an idea how to develop it.. – Sency Jul 23 '11 at 08:20
  • @Kushan: Well, you could indicate how many objects you're going to serialize, then send them all - and on the client, read how many objects to deserialize, then deserialize them. Or you could just serialize them one at a time, and deserialize until the client closes the stream. – Jon Skeet Jul 23 '11 at 08:22
  • @Jon. Could you please post some code sample here. We shall discuss this on that. bcoz, I dont have a clear idea about what you are saying.. – Sency Jul 23 '11 at 08:33
  • @Kushan: I don't have time at the moment, I'm afraid. – Jon Skeet Jul 23 '11 at 08:38
  • @JonSkeet let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/1757/discussion-between-kushan-hasithe-fernando-and-jon-skeet) – Sency Jul 23 '11 at 09:25

2 Answers2

2
  1. For the queue at both the server and the client side you should use BlockingCollection if you are using .net 4.0, for earlier versions use a combination of Queue and AutoResetEvent. check this.

  2. At server side you should use asynchronous methods or just instantiate a new thread to handle each new client and then read the data at that thread. like:

    TcpClient client = tcpListener.AcceptTcpClient();
    ThreadPool.QueueUserWorkItem(new WaitHandle(HandleCleint), client);
    
    private void HandleClient(object clientObject)
    {
        TcpClient client = (TcpClient)clientObject;
        NetworkStream clientStream = client.GetStream();
        //handle the data here
    }
    

Edit: You stated at a comment:

I don't have an idea about how to change my program to send an entire queue to server side

Array or Queue itself is an object:

//at your client side:
bf.Serialize(clientStream, persons);//assume persons is Queue<Person>

//at your server side:
Queue<Person> persons = (Queue<Person>)bf.Deserialize(clientStream);
Community
  • 1
  • 1
Jalal Said
  • 15,906
  • 7
  • 45
  • 68
  • My excuse for putting "entire" word here. What I want is send Person objects one by one to server side. Not the Queue. Btw, Is Queue is Serializable ? – Sency Jul 23 '11 at 08:29
  • @Kushan: Yes, the `Queue` is Serializeable, if you want to send a Person objects one by one then at the server side you can at the `HandleClient` after getting the clientStream, instead of handle it once do `while (true) { Queue persons = (Queue)formatter.Deserialize(stream); /*and then wait for a new data you can do something like: */ while (!stream.DataAvailable) { Thread.Sleep(100);}}` – Jalal Said Jul 23 '11 at 09:02
2

Ok. Finally I found the answer for my question doing some investigations/Testings. I ll post it here for someone else.. :)

In my client side first I have to send how much bytes im gonna send to server. and then send that data.. Like this..

Queue<Person> clientQueue;   // This is the client side queue

IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 15884);
var client = new TcpClient();

NetworkStream clientStream = client.GetStream()

while (disconnectClient)
{
    if (clientQueue.Count > 0)
    {
         Person person = clientQueue.Dequeue();
         using (MemoryStream memoryStrem = new MemoryStream())
         {
              var bf = new BinaryFormatter();
              bf.Serialize(memoryStrem, person);

              byte[] writeData = memoryStrem.ToArray();


              byte[] writeDataLen = BitConverter.GetBytes((Int32)writeData.Length);
              clientStream.Write(writeDataLen, 0, 4);
              clientStream.Write(writeData, 0, writeData.Length);
         }
    }
}
clientStream.Dispose();
client.Dispose();

In Server Side :

Queue<Person> serverQueue;   // This is the server side queue

IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 15884);
TcpListener tcpListener = new TcpListener(ipEndPoint);
tcpListener.Start();

while(true)
{
    TcpClient tcpClient = tcpListener.AcceptTcpClient();
    NetworkStream clientStream = tcpClient.GetStream();

    while (client.Connected)
    {
        if (client.Available >= 4)
        {
            try
            {
                 byte[] readDataLen = new byte[4];
                 clientStream.Read(readDataLen, 0, 4);

                 Int32 dataLen = BitConverter.ToInt32(readDataLen, 0);
                 byte[] readData = new byte[dataLen];

                 clientStream.Read(readData, 0, dataLen);

                 using (var memoryStream = new MemoryStream())
                 {
                      memoryStream.Write(readData, 0, readData.Length);
                      memoryStream.Position = 0;    /// This is very important. It took 4 hrs to identify an error because of this :)

                      BinaryFormatter bf = new BinaryFormatter();
                      Person person = (Person)bf.Deserialize(memoryStream);

                      serverQueue.Enqueue(person);
                 }
            }
            catch { }
        }
    }
    tcpClient.Close();
}
Sency
  • 2,818
  • 8
  • 42
  • 59