Kamigaku
Kamigaku

Reputation: 63

C# Socket keep receiving empty message

I'm trying to train myself and i'm currently building a small Tcp server / client.

I have for the moment 3 small classes that connect, listen for clients and listen to messages. Here are the 3 classes :

public class ServersLauncher
{

    #region Main
    public static void Main(string[] args)
    {
        ServersLauncher sl = new ServersLauncher();
        Console.ReadLine();
        sl._udpServer?.Dispose();
        sl._tcpServer?.Dispose();
    }
    #endregion Main

    private UdpServer _udpServer;
    private TcpServer _tcpServer;

    private ServersLauncher()
    {
        _tcpServer = new TcpServer();
        Socket sc = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 25004);
        sc.Bind(localEndPoint);
        IPEndPoint distantEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 25000);
        sc.Connect(distantEndPoint);
        while (!sc.Connected)
            Thread.Sleep(1000);
        byte[] buffer = Utility.ConvertMessage("Hell world !");
        sc.Send(buffer, buffer.Length, SocketFlags.None);
        sc.Close();
    }

}

On top is the server launcher, it launches the server, create the client and send a message.

public class TcpServer : IDisposable
{

    private readonly int _portTcp = 25000;
    private Socket _socket;
    private Thread _connectionsThread;
    private List<TcpClient> _clients;

    public TcpServer()
    {
        _clients = new List<TcpClient>();

        _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), _portTcp);
        _socket.Bind(endPoint);
        _connectionsThread = new Thread(new ThreadStart(ListenConnections));
        _connectionsThread.Start();
    }

    public void Dispose()
    {
        _connectionsThread.Abort();
        for(int i = 0; i < _clients.Count; i++)
        {
            _clients[i].Dispose();
        }
        _socket.Close();
    }

    private void ListenConnections()
    {
        _socket.Listen(100);
        while (true)
        {
            Socket clientSocket = _socket.Accept();
            _clients.Add(new TcpClient(clientSocket));
        }
    }

}

On top is the TcpServer that listen to the connections and create a client interface when one client connect.

public class TcpClient : IDisposable
{

    private Socket _client;
    private Thread _receiverThread;

    public TcpClient(Socket client)
    {
        _client = client;
        _receiverThread = new Thread(ReceiveMessage);
        _receiverThread.Start();
    }

    public void Dispose()
    {
        _receiverThread.Abort();
    }

    private void ReceiveMessage()
    {
        while (true)
        {
            byte[] buffer = new byte[1024];
            _client.Receive(buffer);
            Utility.DisplayThread("A message has been received : " + Encoding.ASCII.GetString(buffer).Trim());
        }
    }

}

And here is the TcpClient that store the socket client and listen for messages. Nothing that complicated but i have an issue with the reading of the message. Right now, if i launch the program, the client connect but then... non stop messages ! I receive one "Hell world" then empty messages. I read the documentation of the Receive method for the Socket and it seems that it should block and wait for a message to pursue is routine. Do i do something wrong somewhere ? Do i need to flush the stream from the client before disconnecting ? Thanks for helping !

Upvotes: 0

Views: 4542

Answers (2)

sBanda
sBanda

Reputation: 379

Reason for receiving empty messages is that your client socket remains connected.

You can wait to receive more messages with your client, if that is what you want try this:

 private void ReceiveMessage()
        {
            while (true) {
                if(_client.Available > 0) {
                    byte[] buffer = new byte[1024];
                    _client.Receive(buffer);
                    Console.WriteLine("A message has been received : " + Encoding.ASCII.GetString(buffer));
                }
            }
        }

if(_client.Available > 0) checks if there are any number of bytes of data received from the network and available to be read.

Update me on how it goes;

Good luck;

Upvotes: 3

pookie
pookie

Reputation: 4142

Hmm, I'm not sure what behaviour you expect to see.

You create a new ServerLauncher and then when doing so, you do the following:

sc.Connect(distantEndPoint);
while (!sc.Connected)
   Thread.Sleep(1000);
byte[] buffer = Utility.ConvertMessage("Hell world !");
sc.Send(buffer, buffer.Length, SocketFlags.None);
sc.Close();

This connects, waits until connected, sends a message and then closes.

Your main method then calls Console.ReadLine();...

If your server is closed, no more messages will come through. Remove the sc.Close(); line (or only call it when some flag is called like X)

Perhaps you should create a loop and send message from the loop, or better, pass messages from the commandline.

Upvotes: 0

Related Questions