0

I'm creating an async TCP Server that works kinda like a chat room, or at least it should. When a new client connects to the server he receives a welcome message and also everytime he sends a message, the server echos it back. It works well when only one client is connected, but when another one connects, he doesn't receive the welcome msg nor the echos.

Here's some of my code.

private void btn_startserver_Click(object sender, EventArgs e)
{
    server = new Socket(AddressFamily.InterNetwork,
        SocketType.Stream, ProtocolType.Tcp); //Populates the Server obj. 
    IPEndPoint iep = new IPEndPoint(IPAddress.Any, 23);
    server.Bind(iep);
    server.Listen(5);
    server.BeginAccept(new AsyncCallback(AcceptConn), server);
    WriteOnLog("Waiting for incoming connections...");
    Thread t1 = new Thread(() => verifyCon(server));
    t1.Start();
}

public void AcceptConn(IAsyncResult iar)
{
    Socket oldserver = (Socket)iar.AsyncState;
    Socket client = oldserver.EndAccept(iar);
    clientList.Add(client);
    WriteOnLog("Connected to: " + client.RemoteEndPoint.ToString());
    string stringData = "Connected Successfully\r\nWelcome to the Server\r\n";
    byte[] message1 = Encoding.UTF8.GetBytes(stringData);
    client.BeginSend(message1, 0, message1.Length, SocketFlags.None,
        new AsyncCallback(SendData), client);
    WriteOnClients(client.RemoteEndPoint.ToString(), "add");
}

void SendData(IAsyncResult iar)
{
    Socket client = (Socket)iar.AsyncState;
    int sent = client.EndSend(iar);
    client.BeginReceive(data, 0, size, SocketFlags.None,
        new AsyncCallback(ReceiveData), client);
}

void ReceiveData(IAsyncResult iar)
{
    Socket client = (Socket)iar.AsyncState;
    string curClient = client.RemoteEndPoint.ToString();
    int recv = client.EndReceive(iar);
    if (recv == 0)
    {
        client.Close();
        WriteOnLog("Connection lost with " + curClient);
        WriteOnClients(curClient, "remove");
        WriteOnLog("Waiting for client...");
        connectedClients.Remove(curClient);
        server.BeginAccept(new AsyncCallback(AcceptConn), server);
        return;
    }
    string receivedData = Encoding.ASCII.GetString(data, 0, recv);
    WriteOnLog(receivedData);
    byte[] message2 = Encoding.UTF8.GetBytes(receivedData);
    client.BeginSend(message2, 0, message2.Length, SocketFlags.None,
        new AsyncCallback(SendData), client);
}
3
  • 1
    Not related to the current issue, but please pick one encoding and use it consistently. Mixing ASCII and UTF8 looks like a recipe for chaos if not now then soon. Commented Aug 11, 2021 at 6:38
  • Also, be aware that if you want messages, it's up to you to implement some way of identifying them. There's is not a guarantee that each call to Send at the client will be matched to a single call of Receive at the server (and vice versa). TCP is a continuous stream of bytes. Commented Aug 11, 2021 at 6:48
  • Thanks for the tips! I grabbed some of that code and haven't finished modifying it to UTF8. Oh and I will see about identifying the messages! Try to figure a way how to... thanks!!! Commented Aug 11, 2021 at 17:20

1 Answer 1

2

After you handle the first incoming connection (EndAccept), you need to call BeginAccept again to accept the next connection.

Currently you call BeginAccept only during initialization, and when a client disconnects.

Sign up to request clarification or add additional context in comments.

1 Comment

Man, you're great!!! Thanks a lot! You just solved a problem that I was struggling with for a whole week! Thanks so much!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.