Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Client/Server Question

Tdata

Sponsor

Could someone please explain the process required to make a Client/Server application. I haven't a clue how to do more than send Chat messages. Since I currently need to have the MySQL connection string within my program I am finding that I have to package it with a 3rd party program. A few people are seeming to have a problem with that. So I think now is a good point to rewrite to use the proper Client/Server relationship. I can find no tutorials covering this subject, only chat servers. So to place it in a nutshell, Can someone give me an example of a client/server application that sends info back and forth? As simple as you can make it would be helpful.

I'd really like it if I could do something along the lines of:
Code:
 

Client.Connect(svradd, svrport);

result = Client.Send(Login(Username, Password), cltID);

if (result)

//Code here

 
and have the server do this:
Code:
 

Reader = Server.Listen(svrport);

if (Reader != null)

{

 return Reader(); //Reader should = Login(Username, Password); for this Example

}

 
 

Tdata

Sponsor

Unfortunately, I am not interested in p2p networking right now. I just need to know how to setup a server that can receive commands from a client and how to send them. So I need to know how to read the bytestream from the client and send a response which can be read by the client... I know how to Connect using TCP and get the bytedata, no clue how to use it...
 
I'm going to suggest something to you that saved me from hours of hardcoding lines: Go with Binary Serialization. I just got done developing my own Client & Server system. While it looks like you're using C#, I'm sure most of my code (VB.net) can be converted to C#. I actually use a local database for the server (an .sdf), but it should be easy to port to MySQL.

Basically, I created a single DLL that is used by both the Client & Server that contains Serializable Structures:

Code:
[Serializable()]

public struct Message

{

    public string Sender;

    public string Receiver;

    public string Message;

}

[Serializable()]

public struct Login

{

    public string User;

    public string Pass;

}

[Serializable()]

public struct Register

{

    public string User;

    public string Pass;

}

[Serializable()]

public struct AddFriend

{

    public string User;

}

[Serializable()]

public struct FriendList

{

    public List<User> Friends;

}

[Serializable()]

public struct User

{

    public string User;

    public string Status;

}

 

I've given you a few structures as a starting point.

From there, you can use the stream of the client to run Serialization. If you need code examples of that, I can gladly give you some. The reason they use the same DLL is because the structures must be exactly identical, and you can't just put the same structure in each program (tried and it failed). It's a bit more complex to explain the meanings behind so if you need some more help, send me a PM.
 

Tdata

Sponsor

At the moment I am trying to use WCF to do it. Unfortunately, While I can run the Client and server as Localhost, When I try to run them on different machines, IE one for Client and 1 for server. I can't seem to get them to connect.
 
Why use WCF? I can understand wanting to use newer technologies, but using Sockets is powerful in itself. If you really want to use WCF, you should look up some tutorials found on Google and Youtube...even MSDN has some good stuff on it.
 

Zeriab

Sponsor

What are you trying to do?
From my 5 minutes of googling it seems that the main purpose of WCF is to make development of web services easier.?
For example, do you want to create web services which supports WS-Reliable Messaging or WS-Security? Then WCF will probably help you a great deal.
I don't know how much sense it makes to use WCF if you don't want to create and use web services.

For you to talk about managing the bytedata you receive it sounds like you want something much more low-level.
It really depends on what you want to do.

*hugs*
 

Tdata

Sponsor

In a nutshell, I am currently attempting to use Remoteing, IE the Client sees absolutely nothing of how the info is gathered. It is all done by the server and returned to the client.

Code:
 

//Server Main:

ServiceHost host = new ServiceHost(typeof(Impur.Game.Network.Server.Actions), new Uri[] { new Uri("net.[url=pipe://localhost]pipe://localhost[/url]") });

                host.AddServiceEndpoint(typeof(IActions), new NetNamedPipeBinding(), "PipeImpur");

                ServiceBehaviorAttribute attribute = new ServiceBehaviorAttribute();

                attribute.IncludeExceptionDetailInFaults = true;

                host.Open();

                Console.WriteLine("Service is available. Press <ENTER> to exit.");

                Console.ReadLine();

                host.Close();

 
Code:
 

//Server Actions:

 public Player playerData(string username)

        {

            return PlayerData.FromDB(username);

        }

 

Client:
Code:
 

//Client Setup:

this.pipeFactory = new ChannelFactory<IActions>(new NetNamedPipeBinding(), new EndpointAddress("net.[url=pipe://localhost/PipeImpur]pipe://localhost/PipeImpur[/url]"));

            this.pipeProxy = this.pipeFactory.CreateChannel();
Code:
 

//Client Call for playerdata

this.Player = this.pipeProxy.playerData(this.textBox1.Text)

 

WCF was suggested to me as the solution to my problem of knowing what data is being sent and received. Also, I was told that I could connect an ASP.NET site to the server and be able to run the functions there as well... Never got that to work...
 
That's what I do without WCF. Two EXE's can do exactly what you want. I don't want to share code out openly so if you're interested in some starting code I can help you with that.
 

Tdata

Sponsor

It is more along the lines of figuring out how to let a client connect to the server without them having to be within the localhost domain... That seems to be my real issue. (*Note: I realize in the above I am using net.pipes, but that is only because I didn't want to have to set the access controls on every computer I was developing the applications on. If I remember correctly, BasicHttpBinding is what I will need to use.)

Now as for how you do the same thing without WCF, if it works, I'd like to see it. ^_^
 
I think I'll just post the code here for all to see the solution.
This is all the server side code I started with for a base (warning, this is quite large due to the comments for IntelliSense and other comments I've made in the code):
Code:
 

Public Class TCPServer

    Private ServerListener As TcpListener

    Private IncomingClient As TcpClient

    Private ListenThread As System.Threading.Thread

    Private OnlineList As New List(Of Client)

    ''' <summary>

    ''' Raised when a Client Logs in.

    ''' </summary>

    ''' <param name="client">The Client that's logging on.</param>

    ''' <remarks></remarks>

    Public Event Login(ByVal client As Client)

 

    ''' <summary>

    ''' Raised when a Client Logs off.

    ''' </summary>

    ''' <param name="client">The Client that's logging off.</param>

    ''' <remarks></remarks>

    Public Event Logoff(ByVal client As Client)

 

    ''' <summary>

    ''' A message to be stored in the log.

    ''' </summary>

    ''' <param name="message">The message to store.</param>

    ''' <remarks></remarks>

    Public Event Log(ByVal message As String)

 

    ''' <summary>

    ''' Initialize the Server

    ''' </summary>

    ''' <param name="port">Supply the port to open on. If not supplied, the server will default to 6110.</param>

    ''' <remarks></remarks>

    Public Sub New(Optional ByVal port As Integer = 6110I)

        ServerListener = New TcpListener(System.Net.IPAddress.Any, port)

    End Sub

 

    ''' <summary>

    ''' Dispose of the Ark TCPServer.

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub Dispose()

        For Each cli As Client In OnlineList

            Dim msg As New Message With {.Sender = "SERVER", .Receiver = cli.Name, .Message = "LOGOFF"}

            cli.SendMessage(msg)

            UserInteraction.ChangeUserToOffline(cli.Name)

        Next

 

        For Each grp As Groups In GroupList

            grp.Dispose()

        Next

 

        GroupList.Clear()

        ServerListener.Stop()

        IncomingClient.Close()

        ListenThread.Abort()

        UserInteraction.Dispose()

        OnlineList.Clear()

    End Sub

 

    ''' <summary>

    ''' Initialize the Server.

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub Initialize()

        RaiseEvent Log("Starting Server....")

        ServerListener.Start()

        RaiseEvent Log("Server initialized, creating Listener Thread.")

        ListenThread = New System.Threading.Thread(AddressOf Listener)

        RaiseEvent Log("Listener Thread Created, setting to Background.")

        ListenThread.IsBackground = True

        RaiseEvent Log("Starting listener...")

        ListenThread.Start()

        RaiseEvent Log("Server Startup Complete.")

    End Sub

 

    ''' <summary>

    ''' The Listener Sub, constantly looping, waiting for new Clients.

    ''' </summary>

    ''' <remarks></remarks>

    Private Sub Listener()

        Do

            IncomingClient = ServerListener.AcceptTcpClient()

            Dim LingerOption As New System.Net.Sockets.LingerOption(False, 2)

            IncomingClient.LingerState = LingerOption

            Dim Client As New Client(IncomingClient)

            RaiseEvent Log("Client Accepted, registering handlers.")

            AddHandler Client.Message, AddressOf IncomingMessage

            AddHandler Client.ErrorOut, AddressOf ErrorOut

            RaiseEvent Log("Adding to Online List.")

            OnlineList.Add(Client)

            RaiseEvent Log("Waiting for Login Response.")

        Loop

    End Sub

 

That code is for actually setting up the server to accept messages. You might be wondering what this "Client" is...it's a custom class that I'll post later on down. Next is your sub that actually reads the messages:

Code:
 

    Private Sub IncomingMessage(ByVal cli As Client, ByVal obj As Object, ByVal obj_type As Type)

         'My sub is several hundred lines long, but yours can be whatever you want.

    End Sub

 
Not long as you can see, mostly because I focus on Binary Serialization I have code you probably won't utilize so I just stripped down the sub.

There was also an Error Handing Sub, that's right here:
Code:
 

Private Sub ErrorOut(ByVal cli As Client, ByVal err As Exception)

        RaiseEvent Log(String.Format("Exception: {0}{1}Stack Trace: {2}", err.Message, Environment.NewLine, err.StackTrace))

        OnlineList.Remove(cli)

        UserInteraction.ChangeUserToOffline(cli.Name)

        For Each item As Client In GetFriendList(cli)

            item.SendMessage(New Logoff With {.User = cli.Name})

        Next

        RaiseEvent Logoff(cli)

        cli.Dispose()

    End Sub

End Class

 

Finally, that's the entire class! Again, mine's a bit larger due to the fact that I have a lot more stuff in that I did for a base.

Now, here comes the Client Class:

Code:
 

Public Class Client

    Private readThread As Threading.Thread 'Reader thread.

    Private m_Name As String = String.Empty 'client's name.

    Private m_Client As TcpClient 'the tcp client, do not ever dispose this!

    Private BinFormatter As Binary.BinaryFormatter 'The binary formatter that handles our queries.

 

    ''' <summary>

    ''' The Message Received Event.

    ''' </summary>

    ''' <param name="cli">The Client that sent the message.</param>

    ''' <param name="obj">The Object the client sent.</param>

    ''' <param name="obj_Type">What type of object the client sent.</param>

    ''' <remarks></remarks>

    Public Event Message(ByVal cli As Client, ByVal obj As Object, ByVal obj_Type As Type)

 

    ''' <summary>

    ''' The Error Event for a Client.

    ''' </summary>

    ''' <param name="cli">The Client that threw the error.</param>

    ''' <param name="err">The exception data.</param>

    ''' <remarks></remarks>

    Public Event ErrorOut(ByVal cli As Client, ByVal err As Exception)

 

    ''' <summary>

    ''' Our Timer for checking for timeouts.

    ''' </summary>

    ''' <remarks></remarks>

    Private WithEvents TimeoutTimer As New System.Timers.Timer With {.Interval = 5000, .AutoReset = True, .Enabled = False}

 

    ''' <summary>

    ''' Create a new Client.

    ''' </summary>

    ''' <param name="client">The TCP Client that's connecting.</param>

    ''' <remarks></remarks>

    Public Sub New(ByVal client As TcpClient)

        m_Client = client 'Transfer over the TcpClient to this class.

        'create new reading thread.

        readThread = New System.Threading.Thread(AddressOf client_doRead)

        'set it to the background to not disturb the server

        readThread.IsBackground = True

        'start it.

        readThread.Start()

        'create our timeout timer.

        TimeoutTimer.Enabled = True

    End Sub

 

    ''' <summary>

    ''' The infinite doRead() sub. Handles all reading from the client.

    ''' </summary>

    ''' <remarks></remarks>

    Private Sub client_doRead()

        Do

            Try

                'create new formatter

                BinFormatter = New Formatters.Binary.BinaryFormatter()

                'create a generic object

                Dim obj As Object

                'deserialize the stream when a message comes in.

                obj = BinFormatter.Deserialize(m_Client.GetStream)

                'handle the object!

            Catch ex As Exception

                RaiseEvent ErrorOut(Me, ex)

                Me.Dispose()

            End Try

        Loop

    End Sub

 

    ''' <summary>

    ''' Send a Serialized Message to the Client. The Types are in the ArkDLL.

    ''' </summary>

    ''' <param name="message">The Object to send.</param>

    ''' <remarks></remarks>

    Public Sub SendMessage(ByVal message As Object)

        Try

            BinFormatter = New Binary.BinaryFormatter()

            BinFormatter.Serialize(m_Client.GetStream, message)

            BinFormatter = Nothing

        Catch ex As Exception

            RaiseEvent ErrorOut(Me, ex)

        End Try

    End Sub

 

    ''' <summary>

    ''' Get or Set the Name of the Client.

    ''' </summary>

    ''' <value></value>

    ''' <returns></returns>

    ''' <remarks></remarks>

    Public Property Name() As String

        Get

            Return m_Name

        End Get

        Set(ByVal value As String)

            m_Name = value

        End Set

    End Property

 

    ''' <summary>

    ''' Dispose of the Client

    ''' </summary>

    ''' <remarks></remarks>

    Public Sub Dispose()

        m_Name = String.Empty

        BinFormatter = Nothing

        m_Client.Client.Close()

        Try

            readThread.Abort()

            readThread = Nothing

        Catch

        End Try

        GC.Collect()

    End Sub

 

    ''' <summary>

    ''' Check to see if the client has been f**ked.

    ''' </summary>

    ''' <param name="sender"></param>

    ''' <param name="e"></param>

    ''' <remarks></remarks>

    Private Sub TimeoutTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles TimeoutTimer.Elapsed

        Try

            If Not m_Client.GetStream.CanRead AndAlso Not m_Client.GetStream.CanWrite Then

                RaiseEvent ErrorOut(Me, New Exception("The Client has timed out"))

                Me.Dispose()

            End If

        Catch ex As Exception

 

        End Try

    End Sub

 

End Class

 

Now that the client class is created, it can be used to monitor incoming clients and utilize them to their potential...but you have no clue how to actually do this. Unfortunately, the client side code is something you have to come up with from scratch. I would post more code, but it would be like throwing garbage into a landfill; not really making a difference.
 

Tdata

Sponsor

Aside from the fact that it is incomplete and the fact that there are a few VB only functions... Looks interesting... Not sure that I know how to use it though...
 
It's incomplete because there are sections I don't know to fill in for you. I put in the base for you, but it's up to you to fill in what needs to go where.
As for the VB only functions, can you point them out...?

Also just noticed a few subs are wanting a "Type" variable. That's an Enum which I'll post here:
Code:
 

Public Enum Type

'Fill in the types here.

'Example

    1 = Text

End Enum

 

You also need a Structure that correlates to this..
Code:
 

<Serializable()> Public Structure TextStructure

    Public Text As String

End Structure

 

With that enum, you can (in the IncomingMessage Sub) do something like this:
Code:
 

If obj.GetType Is GetType(TextStructure) Then

'Do stuff here

 

Though since IncomingMessage is called by Raising the Event Message, you will end up passing the Structure Type through into the sub which would allow you to do a Select Case statement instead.
 

Tdata

Sponsor

^_^ What I meant by incomplete is that the Misc stuff it missing. Stuff like the Message Struct. Also, I'm not sure what to stub Group in GroupList...

EDIT::
Here let me post the conversion an you will see.

Code:
 

public class TCPServer

{

    // Fields

    private static List<WeakReference> __ENCList = new List<WeakReference>();

    private TcpClient IncomingClient;

    private Thread ListenThread;

    private List<Module1.Client> OnlineList;

    private TcpListener ServerListener;

 

    // Events

    public event LogEventHandler Log;

 

    public event LoginEventHandler Login;

 

    public event LogoffEventHandler Logoff;

 

    // Methods

    public TCPServer([Optional, DefaultParameterValue(0x17de)] int port)

    {

        List<WeakReference> VB$t_ref$L0 = __ENCList;

        lock (VB$t_ref$L0)

        {

            __ENCList.Add(new WeakReference(this));

        }

        this.OnlineList = new List<Module1.Client>();

        this.ServerListener = new TcpListener(IPAddress.Any, port);

    }

 

    public void Dispose()

    {

        List<Module1.Client>.Enumerator VB$t_struct$L0;

        IEnumerator VB$t_ref$L1;

        try

        {

            VB$t_struct$L0 = this.OnlineList.GetEnumerator();

            while (VB$t_struct$L0.MoveNext())

            {

                Module1.Client cli = VB$t_struct$L0.Current;

                Message msg = new Message();

                msg.Sender = "SERVER";

                msg.Receiver = cli.Name;

                msg.Message = "LOGOFF";

                cli.SendMessage(msg);

                object[] VB$t_array$S0 = new object[1];

                Module1.Client VB$t_ref$S0 = cli;

                VB$t_array$S0[0] = VB$t_ref$S0.Name;

                object[] VB$t_array$S1 = VB$t_array$S0;

                bool[] VB$t_array$S2 = new bool[] { true };

                NewLateBinding.LateCall(this.UserInteraction(), null, "ChangeUserToOffline", VB$t_array$S1, null, null, VB$t_array$S2, true);

                if (VB$t_array$S2[0])

                {

                    VB$t_ref$S0.Name = (string) Conversions.ChangeType(RuntimeHelpers.GetObjectValue(VB$t_array$S1[0]), typeof(string));

                }

            }

        }

        finally

        {

            VB$t_struct$L0.Dispose();

        }

        try

        {

            VB$t_ref$L1 = ((IEnumerable) this.GroupList()).GetEnumerator();

            while (VB$t_ref$L1.MoveNext())

            {

                ((Groups) VB$t_ref$L1.Current).Dispose();

            }

        }

        finally

        {

            if (VB$t_ref$L1 is IDisposable)

            {

                (VB$t_ref$L1 as IDisposable).Dispose();

            }

        }

        NewLateBinding.LateCall(this.GroupList(), null, "Clear", new object[0], null, null, null, true);

        this.ServerListener.Stop();

        this.IncomingClient.Close();

        this.ListenThread.Abort();

        NewLateBinding.LateCall(this.UserInteraction(), null, "Dispose", new object[0], null, null, null, true);

        this.OnlineList.Clear();

    }

 

    private void ErrorOut(Module1.Client cli, Exception err)

    {

        LogEventHandler VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0(string.Format("Exception: {0}{1}Stack Trace: {2}", err.Message, Environment.NewLine, err.StackTrace));

        }

        this.OnlineList.Remove(cli);

        object[] VB$t_array$S0 = new object[1];

        Module1.Client VB$t_ref$S1 = cli;

        VB$t_array$S0[0] = VB$t_ref$S1.Name;

        object[] VB$t_array$S1 = VB$t_array$S0;

        bool[] VB$t_array$S2 = new bool[] { true };

        NewLateBinding.LateCall(this.UserInteraction(), null, "ChangeUserToOffline", VB$t_array$S1, null, null, VB$t_array$S2, true);

        if (VB$t_array$S2[0])

        {

            VB$t_ref$S1.Name = (string) Conversions.ChangeType(RuntimeHelpers.GetObjectValue(VB$t_array$S1[0]), typeof(string));

        }

        LogoffEventHandler VB$t_ref$S2 = this.LogoffEvent;

        if (VB$t_ref$S2 != null)

        {

            VB$t_ref$S2(cli);

        }

        cli.Dispose();

    }

 

    private object GetFriendList(Module1.Client cli)

    {

        throw new NotImplementedException();

    }

 

    private object GroupList()

    {

        throw new NotImplementedException();

    }

 

    private void IncomingMessage(Module1.Client cli, object obj, Type obj_type)

    {

    }

 

    public void Initialize()

    {

        LogEventHandler VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0("Starting Server....");

        }

        this.ServerListener.Start();

        VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0("Server initialized, creating Listener Thread.");

        }

        this.ListenThread = new Thread(new ThreadStart(this.Listener));

        VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0("Listener Thread Created, setting to Background.");

        }

        this.ListenThread.IsBackground = true;

        VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0("Starting listener...");

        }

        this.ListenThread.Start();

        VB$t_ref$S0 = this.LogEvent;

        if (VB$t_ref$S0 != null)

        {

            VB$t_ref$S0("Server Startup Complete.");

        }

    }

 

    private void Listener()

    {

        while (true)

        {

            this.IncomingClient = this.ServerListener.AcceptTcpClient();

            LingerOption LingerOption = new LingerOption(false, 2);

            this.IncomingClient.LingerState = LingerOption;

            Module1.Client Client = new Module1.Client(this.IncomingClient);

            LogEventHandler VB$t_ref$S0 = this.LogEvent;

            if (VB$t_ref$S0 != null)

            {

                VB$t_ref$S0("Client Accepted, registering handlers.");

            }

            Client.Message += new Module1.Client.MessageEventHandler(this.IncomingMessage);

            Client.ErrorOut += new Module1.Client.ErrorOutEventHandler(this.ErrorOut);

            VB$t_ref$S0 = this.LogEvent;

            if (VB$t_ref$S0 != null)

            {

                VB$t_ref$S0("Adding to Online List.");

            }

            this.OnlineList.Add(Client);

            VB$t_ref$S0 = this.LogEvent;

            if (VB$t_ref$S0 != null)

            {

                VB$t_ref$S0("Waiting for Login Response.");

            }

        }

    }

 

    private object UserInteraction()

    {

        throw new NotImplementedException();

    }

 

    // Nested Types

    public delegate void LogEventHandler(string message);

 

    public delegate void LoginEventHandler(Module1.Client client);

 

    public delegate void LogoffEventHandler(Module1.Client client);

}

 

public class Client

{

    // Fields

    private static List<WeakReference> __ENCList = new List<WeakReference>();

    [AccessedThroughProperty("TimeoutTimer")]

    private Timer _TimeoutTimer;

    private BinaryFormatter BinFormatter;

    private TcpClient m_Client;

    private string m_Name;

    private Thread readThread;

 

    // Events

    public event ErrorOutEventHandler ErrorOut;

 

    public event MessageEventHandler Message;

 

    // Methods

    public Client(TcpClient client)

    {

        List<WeakReference> VB$t_ref$L0 = __ENCList;

        lock (VB$t_ref$L0)

        {

            __ENCList.Add(new WeakReference(this));

        }

        this.m_Name = string.Empty;

        Timer VB$t_ref$S1 = new Timer();

        VB$t_ref$S1.Interval = 5000.0;

        VB$t_ref$S1.AutoReset = true;

        VB$t_ref$S1.Enabled = false;

        this.TimeoutTimer = VB$t_ref$S1;

        this.m_Client = client;

        this.readThread = new Thread(new ThreadStart(this.client_doRead));

        this.readThread.IsBackground = true;

        this.readThread.Start();

        this.TimeoutTimer.Enabled = true;

    }

 

    private void client_doRead()

    {

        while (true)

        {

            try

            {

                this.BinFormatter = new BinaryFormatter();

                object obj = RuntimeHelpers.GetObjectValue(this.BinFormatter.Deserialize(this.m_Client.GetStream()));

            }

            catch (Exception exception1)

            {

                ProjectData.SetProjectError(exception1);

                Exception ex = exception1;

                ErrorOutEventHandler VB$t_ref$S0 = this.ErrorOutEvent;

                if (VB$t_ref$S0 != null)

                {

                    VB$t_ref$S0(this, ex);

                }

                this.Dispose();

                ProjectData.ClearProjectError();

            }

        }

    }

 

    public void Dispose()

    {

        this.m_Name = string.Empty;

        this.BinFormatter = null;

        this.m_Client.Client.Close();

        try

        {

            this.readThread.Abort();

            this.readThread = null;

        }

        catch (Exception exception1)

        {

            ProjectData.SetProjectError(exception1);

            ProjectData.ClearProjectError();

        }

        GC.Collect();

    }

 

    public void SendMessage(object message)

    {

        try

        {

            this.BinFormatter = new BinaryFormatter();

            this.BinFormatter.Serialize(this.m_Client.GetStream(), RuntimeHelpers.GetObjectValue(message));

            this.BinFormatter = null;

        }

        catch (Exception exception1)

        {

            ProjectData.SetProjectError(exception1);

            Exception ex = exception1;

            ErrorOutEventHandler VB$t_ref$S0 = this.ErrorOutEvent;

            if (VB$t_ref$S0 != null)

            {

                VB$t_ref$S0(this, ex);

            }

            ProjectData.ClearProjectError();

        }

    }

 

    private void TimeoutTimer_Elapsed(object sender, ElapsedEventArgs e)

    {

        try

        {

            if (((!this.m_Client.GetStream().CanRead && !this.m_Client.GetStream().CanWrite) ? 1 : 0) != 0)

            {

                ErrorOutEventHandler VB$t_ref$S0 = this.ErrorOutEvent;

                if (VB$t_ref$S0 != null)

                {

                    VB$t_ref$S0(this, new Exception("The Client has timed out"));

                }

                this.Dispose();

            }

        }

        catch (Exception exception1)

        {

            ProjectData.SetProjectError(exception1);

            Exception ex = exception1;

            ProjectData.ClearProjectError();

        }

    }

 

    // Properties

    public string Name

    {

        get

        {

            return this.m_Name;

        }

        set

        {

            this.m_Name = value;

        }

    }

 

    private Timer TimeoutTimer

    {

        [DebuggerNonUserCode]

        get

        {

            return this._TimeoutTimer;

        }

        [MethodImpl(MethodImplOptions.Synchronized), DebuggerNonUserCode]

        set

        {

            ElapsedEventHandler handler = new ElapsedEventHandler(this.TimeoutTimer_Elapsed);

            if (this._TimeoutTimer != null)

            {

                this._TimeoutTimer.Elapsed -= handler;

            }

            this._TimeoutTimer = value;

            if (this._TimeoutTimer != null)

            {

                this._TimeoutTimer.Elapsed += handler;

            }

        }

    }

 

    // Nested Types

    public delegate void ErrorOutEventHandler(Module1.Client cli, Exception err);

 

    public delegate void MessageEventHandler(Module1.Client cli, object obj, Type obj_Type);

}

 

 public struct Message

{

    private string _receiver;

    private string _sender;

    private string _message;

    public string Sender { get; set; }

    public string Receiver { get; set; }

    public string Message { get; set; }

}

 

 
 
Oh I forgot to remove stuff in the Dispose() sub...sorry. Just remove the references to the Groups, that code was incomplete and I ripped it out (or thought I had).
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top