- Main Page
- Classes
- Files

- File List

# C:/Users/Andreas Schiffler/Desktop/SVN/NewGamePhysics/NewGamePhysics/Networking/InfoLinkTransmitter.cs

    00001 ﻿//-----------------------------------------------------------------------------
    00002 // InfoLinkTransmitter.cs
    00003 // (A. Schiffler, 2009)
    00004 //-----------------------------------------------------------------------------
    00005
    00006 namespace NewGamePhysics.Networking
    00007 {
    00008     using System;
    00009     using System.Collections.Generic;
    00010     using System.Net;
    00011     using System.Net.Sockets;
    00012     using System.Text;
    00013     using System.Threading;
    00014
    00018     public class InfoLinkTransmitter : InfoLinkNetBase
    00019     {
    00023         private const int PollingInterval = 1000;
    00024
    00028         private const int TransmissionInterval = 100;
    00029
    00033         private object syncRoot = new object();
    00034
    00038         private List<InfoLink> transmitQueue = new List<InfoLink>();
    00039
    00043         private volatile bool running = false;
    00044
    00048         private Thread transmitterThread;
    00049
    00053         private long transmitted;
    00054
    00058         private long errors;
    00059
    00064         public InfoLinkTransmitter()
    00065         {
    00066             this.port = InfoLinkNetDefaultPort;
    00067         }
    00068
    00074         public InfoLinkTransmitter(int port)
    00075         {
    00076             this.port = port;
    00077         }
    00078
    00082         public bool Running
    00083         {
    00084             get { return this.running; }
    00085             set { this.running = value; }
    00086         }
    00087
    00091         public long Errors
    00092         {
    00093             get {
    00094                 return Interlocked.Read(ref this.errors);
    00095             }
    00096         }
    00097
    00101         public long Transmitted
    00102         {
    00103             get
    00104             {
    00105                 return Interlocked.Read(ref this.transmitted);
    00106             }
    00107         }
    00108
    00112         ~InfoLinkTransmitter()
    00113         {
    00114             if (this.Connected)
    00115             {
    00116                 this.Close();
    00117             }
    00118         }
    00119
    00123         public void StartTransmitter()
    00124         {
    00125             if (this.Connected)
    00126             {
    00127                 this.Close();
    00128             }
    00129
    00130             this.Open();
    00131             this.transmitterThread = new Thread(new ThreadStart(RunTransmitterThread));
    00132             this.transmitterThread.Name = "InfoLink Transmitter";
    00133             this.transmitterThread.IsBackground = true;
    00134             this.transmitterThread.Start();
    00135         }
    00136
    00140         public void StopTransmitter()
    00141         {
    00142             if (this.Connected)
    00143             {
    00144                 this.Close();
    00145             }
    00146         }
    00147
    00152         public void Transmit(InfoLink infoLink)
    00153         {
    00154             // Simply add the object to the queue for sending
    00155             lock (syncRoot)
    00156             {
    00157                 transmitQueue.Add(infoLink);
    00158             }
    00159         }
    00160
    00165         public void Transmit(InfoLink[] infoLinks)
    00166         {
    00167             // Simply add the object to the queue for sending
    00168             lock (syncRoot)
    00169             {
    00170                 transmitQueue.AddRange(infoLinks);
    00171             }
    00172         }
    00173
    00177         private void RunTransmitterThread()
    00178         {
    00179             this.running = this.Connected;
    00180
    00181             while (this.running)
    00182             {
    00183                 // Check if there is a new infoLink item in the queue
    00184                 InfoLink infoLink = null;
    00185                 lock (syncRoot)
    00186                 {
    00187                     if (transmitQueue.Count > 0)
    00188                     {
    00189                         // Dequeue
    00190                         infoLink = transmitQueue[0];
    00191                         transmitQueue.RemoveAt(0);
    00192                     }
    00193                 }
    00194
    00195                 // Maybe transmit
    00196                 if (infoLink != null)
    00197                 {
    00198                     string message = InfoLinkSerializer.Serialize(infoLink);
    00199                     byte[] sendbuf = Encoding.UTF8.GetBytes(message);
    00200
    00201                     try
    00202                     {
    00203                         int bytesSent;
    00204
    00205                         bytesSent = this.udpClient.Send(sendbuf, sendbuf.Length);
    00206                         if (bytesSent == sendbuf.Length)
    00207                         {
    00208                             Interlocked.Increment(ref this.transmitted);
    00209                         }
    00210                         else
    00211                         {
    00212                             Interlocked.Increment(ref this.errors);
    00213                         }
    00214                     }
    00215                     catch
    00216                     {
    00217                         Interlocked.Increment(ref this.errors);
    00218                     }
    00219
    00220                     // Pace packet transmission
    00221                     Thread.Sleep(TransmissionInterval);
    00222                 }
    00223                 else
    00224                 {
    00225                     // Poll slowly
    00226                     Thread.Sleep(PollingInterval);
    00227                 }
    00228             }
    00229         }
    00230
    00234         private void Open()
    00235         {
    00236             this.udpClient = new UdpClient();
    00237             this.endPoint = new IPEndPoint(IPAddress.Broadcast, this.port);
    00238             this.udpClient.EnableBroadcast = true;
    00239             this.udpClient.Connect(this.endPoint);
    00240             this.Connected = true;
    00241             this.errors = 0;
    00242         }
    00243
    00247         private void Close()
    00248         {
    00249             try
    00250             {
    00251                 this.running = false;
    00252                 this.udpClient.Close();
    00253                 this.transmitterThread = null;
    00254             }
    00255             finally
    00256             {
    00257                 this.Connected = false;
    00258             }
    00259         }
    00260     }
    00261 }