Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6346445
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T21:01:05+00:00 2026-05-24T21:01:05+00:00

I have a TCP Client that mainly runs on mono that I wish some

  • 0

I have a TCP Client that mainly runs on mono that I wish some guidance with, I think I am doing some things wrong, something not needed, etc.

The below code is part of what I use to serve as a sample for my doubts.

  • As you can see once the constructor is called, its when I instantiate the ConcurrentQueues, should I have it instantiated by itself not needing to initiate it from the constructor or the way I am currently doing is the correct one or it doesn’t really matter ?

  • I currently have 3 threds running which I belive I could reduce to 2 or even one but I am a bit insecured for doing that.

    As you can see I have:

    receiveThread for _ReceivePackets
    This one controls all received data from the roomserver

    sendThread for _SendPackets
    This one controls everything that must be sent to the roomserver

    responseThread for _Response
    This will handles all the responses that were queued from the roomserver

    I belive I could merge _SendPackets with _ReceivePackets as one and increase to my class SendPackets wether it is a packet to be sent or one that was delivered, what I am afraid of is that if it has a huge in/out if it would still keep up withou messing things up.

    I have the _Response separated as it will be processing more of the response data per type of reply which I think is fine and don’t think it would work out if I remove it and let the _Response handle it by itself since some packets won’t be readed in just one shot.

  • How far should I rely myself into the _socket.Connected ?

  • I am having some issues to deploy a reconnect, most of the time when I have some connection issue, it doesn’t trigger any errors it just sit in there with the ports open as if it still connected, how should I detect if I am still live or not ?

  • Over all recommendations, advices or online free reading materials ?

Side note: This is a very basic implementation of a chat tcp client for learning that I am currently working on.

using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Collections.Concurrent;
using log4net;

namespace Connection
{
    public class Roomserver
    {
        private static readonly ILog logger = LogManager.GetLogger(typeof(Roomserver));

        private ConcurrentQueue<byte[]> RoomserverReceivedPackets = null;
        private ConcurrentQueue<SendPackets> RoomserverSendPackets = null;

        private AutoResetEvent _queueNotifier = new AutoResetEvent(false);
        private AutoResetEvent _sendQueueNotifier = new AutoResetEvent(false);

        public static byte[] myinfo = null;

        private IPAddress _server = null;
        private int _port = 0;
        private int _roomID = 0;

        private Socket _socket;
        private Status _status = Status.Disconnected;

        private Thread responseThread = null;
        private Thread receiveThread = null;
        private Thread sendThread = null;
        private EndPoint _roomServer = null;

        public bool Connected
        {
            get { return _socket.Connected; }
        }

        public Status GetStatus
        {
            get { return _status; }
        }

        public Roomserver(IPAddress server, int port)
        {
            this._server = server;
            this._port = port;

            RoomserverReceivedPackets = new ConcurrentQueue<byte[]>();
            RoomserverSendPackets = new ConcurrentQueue<SendPackets>();
        }

        public Roomserver(IPAddress server, int port, int roomID)
        {
            this._server = server;
            this._port = port;
            this._roomID = roomID;

            RoomserverReceivedPackets = new ConcurrentQueue<byte[]>();
            RoomserverSendPackets = new ConcurrentQueue<SendPackets>();
        }

        public bool Connect()
        {
            try
            {
                if (_status != Status.Disconnected)
                    this.Disconnect();

                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint remoteEndPoint = new IPEndPoint(_server, _port);

                _socket.Connect(remoteEndPoint);
                _status = Status.Connect;
                _roomServer = (EndPoint)remoteEndPoint;

                receiveThread = new Thread(_ReceivePackets);
                receiveThread.Start();

                sendThread = new Thread(_SendPackets);
                sendThread.Start();

                responseThread = new Thread(_Response);
                responseThread.Start();

                return _socket.Connected;
            }
            catch (SocketException se)
            {
                logger.Error("Connect: " + se.ToString());
                _status = Status.Disconnected;

                return false;
            }
            catch (Exception ex)
            {
                logger.Error("Connect: " + ex.ToString());
                _status = Status.Disconnected;

                return false;
            }
        }

        public bool Disconnect()
        {
            if (_socket.Connected)
            {
                _status = Status.Disconnected;

                if (receiveThread != null && receiveThread.IsAlive)
                {
                    receiveThread.Abort();
                }

                if (responseThread != null && responseThread.IsAlive)
                {
                    responseThread.Abort();
                }

                if (sendThread != null && sendThread.IsAlive)
                {
                    sendThread.Abort();
                }

                try
                {
                    _socket.Close();
                    return true;
                }
                catch (Exception ex)
                {
                    logger.Info("Disconnect " + ex.ToString());
                    _status = Status.Disconnected;
                    return true;
                }
            }
            else
            {
                logger.Info("Not connected ...");
                _status = Status.Disconnected;
                return true;
            }
        }

        public bool SendData(byte[] bytes, bool delay)
        {
            try
            {
                SendPackets data = new SendPackets()
                {
                    Data = bytes,
                    Delay = delay
                };
                RoomserverSendPackets.Enqueue(data);
                _sendQueueNotifier.Set();
                return true;
            }
            catch (Exception ex)
            {
                logger.Error("SendData " + ex.ToString());
                return false;
            }
        }

        private void _SendPackets()
        {
            while (_socket.Connected)
            {
                _sendQueueNotifier.WaitOne();
                while (!RoomserverSendPackets.IsEmpty)
                {
                    SendPackets packet = null;
                    if (RoomserverSendPackets.TryDequeue(out packet))
                    {
                        try
                        {
                            if (packet.Delay)
                            {
                                Thread.Sleep(1000);
                                _socket.Send(packet.Data);
                            }
                            else
                                _socket.Send(packet.Data);
                        }
                        catch (SocketException soe)
                        {
                            logger.Error(soe.ToString());
                        }
                    }
                }
            }
        }

        private void _ReceivePackets()
        {
            bool extraData = false;
            MemoryStream fullPacket = null;
            int fullPacketSize = 0;

            while (_socket.Connected)
            {
                try
                {
                    byte[] bytes = new byte[65536];
                    int bytesRead = _socket.ReceiveFrom(bytes, ref _roomServer);
                    int packetSize = 0;
                    int reply = 0;

                    byte[] data = new byte[bytesRead];
                    Array.Copy(bytes, data, bytesRead);

                    MemoryStream bufferReceived = new MemoryStream(data, 0, data.Length);
                    using (var reader = new BinaryReader(bufferReceived))
                    {
                        packetSize = (int)reader.ReadInt32() + 4;
                        reply = (int)reader.ReadByte();
                    }

                    if (!extraData && packetSize <= bytesRead)
                    {
                        if (data.Length > 0)
                        {
                            RoomserverReceivedPackets.Enqueue(data);
                            _queueNotifier.Set();
                        }
                    }
                    else
                    {
                        if (!extraData)
                        {
                            fullPacket = new MemoryStream(new byte[packetSize], 0, packetSize);
                            fullPacket.Write(data, 0, data.Length);
                            fullPacketSize = data.Length;
                            extraData = true;
                        }
                        else
                        {
                            if (fullPacketSize < fullPacket.Length)
                            {
                                int left = (int)fullPacket.Length - fullPacketSize;
                                fullPacket.Write(data, 0, (left < data.Length) ? left : data.Length);
                                fullPacketSize += (left < data.Length) ? left : data.Length;

                                if (fullPacketSize >= fullPacket.Length)
                                {
                                    extraData = false;
                                    RoomserverReceivedPackets.Enqueue(fullPacket.ToArray());
                                    _queueNotifier.Set();
                                    fullPacket.Close();
                                }
                            }
                        }
                    }
                }
                catch (SocketException soe)
                {
                    logger.Error("_ReceivePackets " + soe.ToString());
                }
                catch (Exception ex)
                {
                    logger.Error("_ReceivePackets " + ex.ToString());
                }
            }
        }

        private void _Response()
        {
            while (_socket.Connected)
            {
                _queueNotifier.WaitOne();

                while (!RoomserverReceivedPackets.IsEmpty)
                {
                    byte[] data = null;
                    if (RoomserverReceivedPackets.TryDequeue(out data))
                    {
                        MemoryStream bufferReceived = new MemoryStream(data, 0, data.Length);
                        using (var reader = new BinaryReader(bufferReceived))
                        {
                            int packetSize = (int)reader.ReadInt32();
                            byte reply = reader.ReadByte();

                            switch (reply)
                            {
                                case 0x01: // Login request
                                    break;
                                case 0x02: // Login accepted
                                    break;
                                case 0x03: // Enter room
                                    break;
                                case 0x04: // Members list
                                    break;
                                case 0x05: // Send Chat
                                    break;
                                case 0x06: // Receive Chat
                                    break;
                                case 0x07: // Receive Announcement
                                    break;
                                case 0x08: // Send Announcement
                                    break;
                                case 0x09: // Wrong password errors
                                    _status = Status.RoomError;
                                    break;
                                case 0x10: // Send Whisper
                                    break;
                                case 0x11: // Receive Whisper
                                    break;
                                case 0x12: // Leave Room
                                    break;
                                case 0x13: // Disconnect
                                    break;
                            }
                        }
                    }
                }
            }
        }
    }
}

On another classes I have:

public class SendPackets
{
    public byte[] Data { get; set; }
    public bool Delay { get; set; }
}

public enum Status
{
    Disconnected = 0,
    Connect,
    EnterRequest,
    RoomError,
    Connected
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T21:01:06+00:00Added an answer on May 24, 2026 at 9:01 pm
    • Use a Dictionary<int, ICommandHandler> instead of your switch statement
    • Switch to asynchronous sockets
    • Read up on Single Responsibility Principle.
    • Use .NET naming convention

    Then come back and ask a more specific question if you want a more specific answer.

    Update to answer the comment

    Instead of:

    switch (reply)
    {
        case 0x01: // Login request
            break;
        case 0x02: // Login accepted
    

    do:

    public interface ICommandHandler
    {
        void Handle(byte[] packet);
    }
    
    public class LoginHandler : ICommandHandler
    {
        public void Handle(byte[] packet) 
        {
            // handle packet data here
        }
    }
    
    var myHandler = new LoginHandler();
    myServer.Register(1, myHandler);
    

    And then in your socket class:

    public class MyServer
    {
         Dictionary<int, ICommandHandler> _handlers;
    
         public void Register(int functionId, ICommandHandler handler)
         {
              _handlers[functionId] = handler;
         }
    
         private void _Response()
         {
    
               // .. alot of stuff ..
               _handlers[reply].Handle(memoryStream);
    
         }
    

    Note that the example is far from complete and you might want to send in a context class instead of just the memory stream.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a server application that receives some special TCP packet from a client
Assume that i have created a client TCP Socket in Activity A. I want
I have a Client program by tcp connection that send data to a server.
I have a client TCP socket that writes a few bytes every five seconds,
I have a client tcp socket (in c++) that has a loop where it
I have one tcp client that need read data via tcp but i need
I have a Java client that connects to a C++ server using TCP Sockets
I have two utilities written in C++, TCP/IP server and client that I have
It is possible to have WCF Client that connects persistantly using duplex over net.tcp
I am trying to develop a TCP client that runs on mobile devices using

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.