Nourgalaby
Nourgalaby

Reputation: 21

using multiple threads to send packets in a socket

intro

I am trying to use threads to send for example 5 packets using 5 threads at the same time (Making Reliable UDP Selective repeat protocol I will later add acknowledgement and simulate loss)

I am a beginner to socket programming so I am not sure if this approach is right

All the packets gets send and I re-order then at the client side ( attached with a sequence number to order) .

-I divide the packets into bytes in a list of byte[] and add sequence number

-pass each packet to the child function in a new thread to send (MAX 5 threads then wait) when I use one thread to send file gets send successful but when I use 5 threads to send the same packets file get corrupted (data scrambled)

So what happens when two threads calls Socket.Send(data);

does it synchronize?

I Made some test and here are the results When I wait between each thread start. the problem goes way( the file is received successfully )

I tried making the send function locked so it can only gets accessed by one thread at a time, but that didn't work

all other parts of code are tested so i am sure it is a threads problem

So how do I use multiple threads to send packets using the same socket ?

code

      for (i = 0; i < pck_count; i++)
    {


  while (EMPTY_THREADS <= 0);//wait for any thread to finish
     //SIZE = windows size = is number of packets to send at one time =                     threads no
 //then try to send SIZE (5) packets from it: 
 int j = 0;
 for (j = 0; j < SIZE; j++)
 {



     if (j + i >= pck_count)
     {
         break;

     }
     //if packet not already sent , send it
     if (!status[i + j].sent && (j + i < pck_count))
     {
        // Console.WriteLine("Sending Packet:" + (i + j) );

         status[i + j].sent = true; //
         status[i + j].ack = true; // TO REMOVE 



         try
         {
             makeThread(Remote, j, i, newsocket);
          //   Thread.Sleep(150); // this makes it work   

         }
         catch (Exception e) {
             Console.WriteLine("ERROR:" + e.Message);
         }


     }




}

Make Thread:

public static void makeThread(EndPoint Remote, int j,int i,Socket newsocket)
    {
        EMPTY_THREADS--;
        thread[j] = new Thread(

               () => startChild(msgs[i + j], Remote, j,newsocket));
        thread[j].Start();

    }

child:

 static void startChild(myMessage packet, EndPoint Remote, int k,Socket newsocket  )
  {

   Console.WriteLine("Sending PACK" + packet.data.Length +" "+ packet.seq_no);
  byte[] data = new byte[1024];



       newsocket.ReceiveTimeout = 1000;

       int sentbytes = 0;

    `//convert packet from object to data array 
       data = serialize(packet);
       newsocket.Connect(Remote);

           sentbytes = newsocket.Send(data);

       //newsocket.Sendto(data,remote); //tried Sendto() with same effect

    //   newsocket.Close();
       EMPTY_THREADS++;
  }

Upvotes: 1

Views: 1838

Answers (1)

Nourgalaby
Nourgalaby

Reputation: 21

@Micky yes you're right this fashion is wrong and corrupts the data, the solution was to use a single thread and a single socket to send packets in a normal loop, and use threading for timers and acknowledgement only

Upvotes: 1

Related Questions