0

I want to write a Multiplayer game with tcp. The Sender works and sends the data but after the Receiver changes the text of the label and the Location of the PictureBox nothing happens. I debuged it and found out that the label have the new Text but It doesn't show it in the window. I googled a bit and found out that my main thread is blocked or something. But I can move the second player.

Multiplayer.cs:

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;

namespace Game
{
class Multiplayer
{
    public string ClientAdress;


    public void StartSession(int port)
    {
        Form1 form1 = new Form1();
        while (true)
        {
            try
            {
                TcpListener listener = new TcpListener(IPAddress.Any, port);
                listener.Start();
                Socket socket = listener.AcceptSocket();
                byte[] b = new byte[100];
                int k = socket.Receive(b);

                string update = null;

                for (int i = 0; i < k; i++)
                {
                    update += Convert.ToChar(b[i]).ToString();
                }
                IPEndPoint remoteIPEndPoint = socket.RemoteEndPoint as IPEndPoint;
                ClientAdress = remoteIPEndPoint.Address.ToString();
                form1.GetData(ClientAdress, update);
                socket.Close();
                listener.Stop();
            }
            catch (Exception ex)
            {
                form1.Exception(ex);
            }
        }
    }

    public void JoinSession(string ipadress, int port)
    {
        Form1 form1 = new Form1();
        {
            try
            {
                TcpClient tcpclnt = new TcpClient();
                tcpclnt.Connect(ipadress, port);

                Stream stm = tcpclnt.GetStream();
                ASCIIEncoding asen = new ASCIIEncoding();

                string message = form1.SendData();

                byte[] ba = asen.GetBytes(message);
                stm.Write(ba, 0, ba.Length);
                byte[] bb = new byte[100];
                int k = stm.Read(bb, 0, 100);
                tcpclnt.Close();
                form1.senderRunning = false;
            }
            catch (Exception ex)
            {
                form1.Exception(ex);
                form1.senderRunning = false;
            }
        }
    }
}
}

Button3:

        Multiplayer mp = new Multiplayer();
    private void button3_Click(object sender, EventArgs e)
    {
        if (!startjoinmenu)
        {
            Thread Listener = new Thread(delegate () { mp.StartSession(Int32.Parse(textBox2.Text)); });
            if (!ThreadisRunning)
            {
                ThreadisRunning = true;
                Listener.Start();
            }
        }
        else
        {
            if (!senderRunning)
            {
                Thread Sender = new Thread(delegate () { mp.JoinSession(textBox1.Text, Int32.Parse(textBox2.Text)); });
                senderRunning = true;
                Sender.Start();
            }
        }

GetData:

public void GetData(string client, string data)
    {
        try
        {
            string dataX;
            string dataY;
            int positionOf = data.IndexOf(";");

            dataX = data.Substring(0, positionOf);
            dataY = data.Substring(positionOf + 1, data.Length - positionOf - 1);
            //enemyplayer.Location = new Point(Int32.Parse(dataX), Int32.Parse(dataY));

            enemyplayer.Left = Int32.Parse(dataX);
            enemyplayer.Top = Int32.Parse(dataY);

            label3.Text = "Connected with: " + client + "!";

        }
        catch (Exception ex)
        {
            Exception(ex);
        }
    }

SendData:

    public string SendData()
    {
        string playerX = player.Location.X.ToString();
        string playerY = player.Location.Y.ToString();
        return playerX + ";" + playerY;
    }
Javes
  • 3
  • 2
  • Why are you constantly opening and closing the connection after each message? – jdweng Mar 30 '18 at 14:48
  • new Form1() in this code is very unlikely to be correct. You have to use the reference of the form object you are looking at. That will require rejiggering the code substantially, use (Form1)Application.OpenForms[0] if you are desperate. – Hans Passant Mar 30 '18 at 15:13

1 Answers1

0

It looks to me like you are using a while(true) statement in your StartSession method. This would cause your main thread to become blocked as the UI only updates when all the methods have finished executing (and in this case with a while (true) it never does finish executing the method).

To overcome this issue, you can use the Application.DoEvents(); method. You can read more about this here. This will tell the application to process other events that are waiting to be executed (like repainting the UI to reflect the changes you made the UI objects in your code). So in your code, I would perhaps do it as follows:

public void StartSession(int port)
{
    Form1 form1 = new Form1();
    while (true)
    {
        try
        {
            // ...

            form1.GetData(ClientAdress, update);

            // Tell the application to execute other events that are in queue
            Application.DoEvents();

            // ...
        }
        catch (Exception ex)
        {
            form1.Exception(ex);
        }
    }
}
Ivan Kahl
  • 598
  • 2
  • 11
  • Didn't work, but does the loop block the ui thread even when it is started in another thread? – Javes Mar 30 '18 at 16:22